続行:「for」、「while」、または「until」ループでのみ意味があります。

続行:「for」、「while」、または「until」ループでのみ意味があります。

次の反復に進むために特定の基準(A)を確認するループがあります。skip()という関数を呼び出すと、continueループ(B)が表示されないため、子プロセスで呼び出されたように見えることに気づきました。さらに、eval文字列に依存する提案された回避策は機能しません(C)。

# /usr/bin/bash env

skip()
{
    echo "skipping : $1"
    continue   
}

skip_str="echo \"skipping : $var\"; continue"

while read -r var;
do
    if [[ $var =~  ^bar$  ]];
    then
        # A
        #        echo "skipping : $var"
        #        continue
        # B
        #        skip "$var" #  continue: only meaningful in a `for', `while', or `until' loop
        # C
        eval "$skip_str"
    fi
    echo "processed: $var"
done < <(cat << EOF 
foo
bar
qux
EOF
        )

方法C:

$ source ./job-10.sh
processed: foo
skipping : 
processed: qux

また見なさい:

Bashの機能は子プロセスとして実行されますか?

PS1:後で必要< <なく理由を教えてくれる人はいますか?<done

PS2:whileしたがって、タグが見つかりません。for

答え1

関数は同じプロセスで実行されますが、ループと構文が異なります。他のほとんどすべてのプログラミング言語では、break関数内または関数を使用して外部ループに影響を与えることはできません。continue

しかし実際にはシェルでは指定されていない:

continue [n]
もしN指定されたら、継続ユーティリティは一番上に戻る必要があります。Nthにはfor、while、またはUntilループが含まれています。もしN指定しない、続行は次のように動作します。N1 と指定されます。 [...]

[...]囲むループがない場合、アクションは指定されません。

取得する内容はシェルによって異なります。

Bashはエラーを発生させ、以下を無視しますcontinue

$ bash -c 'f() { continue; }; for x in a b c; do f; echo $x; done; echo done'
environment: line 0: continue: only meaningful in a ‘for’, ‘while’, or ‘until’ loop
a
environment: line 0: continue: only meaningful in a ‘for’, ‘while’, or ‘until’ loop
b
environment: line 0: continue: only meaningful in a ‘for’, ‘while’, or ‘until’ loop
c
done

Kshはこれを静かに無視します。

$ ksh -c 'f() { continue; }; for x in a b c; do f; echo $x; done; echo done'
a
b
c
done

Dash、Yash、Zshは実際にこれを適用しますが:

$ dash -c 'f() { continue; }; for x in a b c; do f; echo $x; done; echo done'
done

同様の考慮事項が使用法に適用できると予想しましたが、eval実際にはそうではありません。少なくとも私は殻の間に何の違いも見ることができません。

ほとんどしないでください。ちょうど書いてください:

while read -r var;
do
    if [[ $var =~  ^bar$  ]];
    then
        echo "skipping '$var'"
        continue
    fi
    echo "processed: $var"
done

答え2

問題は、関数が実行されたときにループ内になくなったことです。サブシェルにはありませんが、ループ内にもありません。関数に関する限り、これは別のコードスニペットなので、どこで呼び出されるのかわかりません。

その後、実行するとeval "$skip_str"未定義の時間に$var設定したため、値はありません。これは実際に期待どおりに機能するはずです。何の理由もなく非常に複雑で危険です(入力を100%制御しない場合)。skip_string$var

#! /usr/bin/env bash

while read -r var;
do
  skip_str="echo \"skipping : $var\"; continue"
  if [[ $var =~  ^bar$  ]];
  then
    eval "$skip_str"
  fi
  echo "processed: $var"

done < <(cat << EOF 
foo
bar
qux
EOF
        )

それ…あまりきれいではありません。個人的には、私は関数を使ってテストし、テスト結果に対処します。このように:

#! /usr/bin/env bash

doTest(){
  if [[ $1 =~  ^bar$  ]];
  then
    return 1
  else
    return 0
  fi
  
}

while read -r var;
do
  if doTest "$var"; then
    echo "processed: $var"
  else
    echo "skipped: $var"
    continue
  fi

## Rest of your code here

done < <(cat << EOF 
foo
bar
qux
EOF
        )

あなたの目標が何であるかを説明してください。

< <最後に、それ以降は必要ありdoneません< <()。次の<一般的な入力リダイレクトです<()プロセスの交換これは、コマンドの出力をファイル名として処理できるトリックです。

そのような追加の操作を繰り返さないために関数を使用する場合は、関数echo "skipping $1"にさらにロジックを移動してループがあるようにします。このような:協会

関連情報