まで/同時にそしてchain$か。

まで/同時にそしてchain$か。

終了コードで終了するまでコマンドを繰り返したかったので、0次のことを試しました。

$ while/until $?; do $command; done

しかし、 and not のuntil/whileようなブール値のみを許可するようです。true/false0/1

私は似たようなものや何かを逃しましたか[[ ]]

答え1

whileキーワードuntil注文する彼らの主張で。コマンドが「成功」を示すゼロ終了状態を返すと、whileループ本文内のコマンドが実行されuntilます。いいえループ本体内でコマンドを実行します。

whileあなたのコードは、and untilwith $?(最も最近のコマンドの終了ステータス)をコマンドとして使用しているようです。名前が整数のコマンドがシステムに存在しない場合は機能しません。何会議タスクはtestコマンドを使用してと比較することです0

until test "$?" -eq 0; do some-command; done

または略語を使用testして

until [ "$?" -eq 0 ]; do some-command; done

これで問題は、明らかに$?ループに入るとゼロになり、ループが一度実行されるのを防ぐことです。コマンド自体が終了状態を or に直接提供するようにする方がwhile合理的ですuntil(たとえば、ループの前に呼び出してゼロ以外の値に初期化したい場合以外は奇妙に$?見えます)。false

標準のPOSIXを使用する(Bourneではありませんが、今は重要ではありません)シェル構文:

while ! some-command; do continue; done

または(BourneとPOSIX)、

until some-command; do continue; done

両方のコマンドは、some-commandゼロ終了ステータス(「成功」)が返されるまで実行されます。繰り返しごとに、continueループ本体の内部のキーワードを実行します。実行はcontinueループの次の反復に即座にジャンプしますが、これを使用して、たとえば、sleep 5各反復で短い遅延が発生したり、何も実行しないよう:にすることができます。

別の変形は無限コマンドが成功すると終了するループ:

while true; do some-command && break; done

または、より冗長で読みやすくするためにスペースを追加するには

while true; do
    if some-command; then
        break
    fi
done

あなたが本当に唯一の時間必要$?次のように、一定期間にわたって値を追跡する必要がある場合に使用されます。

somefunction () {
    grep -q 'pattern' file
    ret=$?
    
    if [ "$ret" -ne 0 ]; then
        printf 'grep failed with exit code %s\n' "$ret"
    fi >&2
    
    return "$ret"
}

上記のコードでは、$?テストによって終了ステータスがリセットされ、[ "$ret" -ne 0 ]それを別の変数に保存しないと、その値を印刷したり関数から返すことはできません。


もう一つの指摘すべき点は、あなたが使用しているようです。ひも$command(引用符なし)をコマンドとして使用します。これは〜になりますはるかに良い変数に格納されたコマンドを実行するには、配列を使用します。

thecommand=( awk -F ',' 'BEGIN { "uptime" | getline; split($4,a,": "); if (a[2] > 5) exit 1 }' )

while ! "${thecommand[@]}"; do sleep 5; done

(このサンプルコードは、1分平均システム負荷が5未満になるまで5秒ごとに待機します。)

配列を使用して拡張を参照することで、"${thecommand[@]}"シェルが文字列を単語に分割し、各単語にファイル名ワイルドカードを適用する方法を心配することなくコマンドを実行できます。

また、見ることができます変数に保存されたコマンドをどのように実行できますか?あなたの質問に関する追加情報です。

答え2

次のことができます。

false; while [[ $? -ne 0 ]]; do
  command
done

ここでは、false最初にゼロ以外の値に設定され、$?ループを少なくとも1回実行できます。指定されたコマンドは、ゼロ終了状態で終了するまでループで実行されます。

関連情報