以下のループの動作は、while [ 1 ]
のループと同じです。どうしてこんなことに?
while [ 0 ]; do
echo "hello"
done
シェルの単一の角括弧はtest
(個別のコマンドまたはシェルの組み込み)の同義語であるため、[ 0 ]
はtest 0
と同じ意味です。 test
は、マンページで確認できるように、ファイルの属性を比較およびテストするためのものです。比較、ファイルテスト、または実行できる他の操作のような式が指定されていない場合、代わりに、引数が存在し、空でない文字列であるかどうかをテストします。 0
も1
もテストに適切な入力ではありません。空でない文字列テストは単純に成功し、whileループは永久にループします。
代わりに試すこともできます
while false; do
echo "hello"
done
false
をtrue
に置き換える可能性があります。あるいは、(( ))
を使用することもできます:
while (( 0 )); do
echo "hello"
done
これはほとんどの言語と同じように動作し、0は失敗/偽、1は成功/真を意味します。
ここで値0は数値定数としてではなく、文字列として機能します。これらのテストはすべて、正常終了ステータスを生成する効果が同等です。
[ A ]
[ "XYZ" ]
[ 0 ]
これらは、失敗した終了ステータスを生成します。
[ ]
[ "" ]
論理trueと評価される非空白の引数があります。これにより、次のようなことが可能になります。
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
変数UNDER_NUCLEAR_ATTACK
は、trueを示すには空白以外の値に設定され、falseを示すには未設定または空です。
!
演算子を適用して、ロジックを逆にすることができます。
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
数値条件を評価するには、数値テスト演算子を使用する必要があります。
while [ $A -gt $B ] ; do ...
A
とB
に10進整数のように見える文字列が含まれている場合、それらは数値のように比較され、A
がB
より大きい場合、ループが実行されます。したがって、UNDER_NUCLEAR_ATTACK
が空白または非空白の文字列型のブール値ではなく、実際には0
(false)またはその他の値(true)の数値ブール値であるとします。その場合、次のようにテストを記述します。
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...