ショートカット:、ステートメントの(expr1 && expr2)
代わりに。if ... fi
ループを介して、...を生成したい場合はできますかexpr1
?expr2
おもちゃの例は次のとおりです。
$ for cond in {0,0,0}; do if [[ $cond = 0 ]]; then echo 0; else echo 1; break; fi; done && echo "true" || echo "false"
0
0
0
true
$ for cond in {0,1,0}; do if [[ $cond = 0 ]]; then echo 0; else echo 1; break; fi; done && echo "true" || echo "false"
0
1
true
最初の文だけを返し、2番目の文は返すようにif...fi
この文をどのように変更できますか?内部に交換すると、ターミナルウィンドウが閉じます。true
false
echo 1
exit
答え1
ループの終了状態は、ループ内で実行された最後のコマンドの終了状態(echo
または)break
であり、両方の終了状態は通常ゼロです。したがって、条件を保存して状態を確認する必要があります。次の機能を使用することをお勧めします。
loopcheck() {
for cond in {0,1,0}; do
if [[ $cond = 0 ]]; then
echo 0;
else
ret=$?; # preserve exit status of test
echo 1;
return $ret; # pass it on
fi;
done
}
loopcheck && echo "true" || echo "false"
別のオプションは、$ret
上記のように保存し、ループの外側でその値をチェックすることです。
答え2
私は取るこれ質問に示されている内容に近いので、他の答えよりも優れています(有用ですが)。
$ (for cond in {0,1,0}; do if [[ $cond = 0 ]]; then true; else false; exit; fi; done) && echo "true" || echo "false" false
答え3
ループリレーfor name in ...
の最後の実行コマンドの終了状態です。
break
ループを実行すると、break
コマンド自体の終了状態がデフォルトでゼロであるため、中継されるため、以降のテストは同じになりますfor
。&&
done
true
この問題を解決する1つの方法は、独自の答えで述べたとおりです。これは素晴らしい、きれいなシェルであり、すべてのPOSIX互換シェルでうまく機能します。
しかし、サブシェルとして機能を完全に共有しないため、欠点があります。実行環境1とその「外部」シェル。実行が開始されるとそれを継承しますが、実行が完了すると「外部」親に再び「伝播」しません。つまり、たとえば、ループ内で設定または変更されたすべての変数は、後でループの外にはありません。より。
Bashには代替手段があります。サブシェルの使用を避け、引き続き使用できますが、終了するループの数が常に無効であるため、引数を渡してbreak
失敗するように強制できます。 Bashはエラーメッセージを表示しますが、リダイレクトしてそれを無音に設定できます。-1
-1
2>/dev/null
ただし、この動作はPOSIXと完全に互換性がないと見なされますbreak
。特殊内蔵、そしてエラーを発生させる「特殊組み込み」出なければならない非対話型シェル(例:スクリプト)。
1[… ]。変更サブシェル環境は影響を受けません。シェル実行環境。 [...]