うまく動作する次のスクリプトがあります。
!/bin/bash
a=12
while [ $a -gt 10 ]
do
echo "$a"
a=$(($a-1))
done
echo "done"
「do」の上に「echo Something」行を追加すると、その行に構文エラーが表示されることが予想されます。迂回するようで[ $a -gt 10 ]
無限ループになります。どうすればこれが起こりますか?
答え1
~からバッシュマニュアル:
while
このコマンドの構文は次の
while
とおりです。しかし、テストコマンド;する後続のコマンド; 完璧consequent-commands
終了ステータスが0の間test-commands
実行されます。戻り状態は、最後に実行されたコマンドの終了状態、またはconsequent-commands
実行されたコマンドがない場合は0です。
メモ: test-commands
、複数形。テストでは複数のコマンドを使用できるため、以下はコマンドリストを[ $a -gt 10 ]; echo "$a"
テストとして使用する完全に有効なループです。
while [ $a -gt 10 ]
echo "$a"
do
a=$(($a-1))
done
コマンドは[ $a -gt 10 ]
失敗したり失敗したりすることはできませんがecho
(テキストの書き込みに失敗したり他のエラーが発生しない限り)(ほぼ)常に成功します。決定的なテストコマンドの終了状態は常に成功し、ループは常に実行されます。
答え2
からman bash
:
そしてlist-1; do list2; did whileコマンドは、次の期間中に
リストを実行し続けます。list-2
最後のコマンドリストはlist-1
終了状態 0 を返します。
これは、aにlist
複数のコマンドを含めることができることを意味します。これは、セミコロンまたは改行文字で区切られます。
したがって、これは完全に機能します。
#!/bin/bash
a=12
while
echo something
echo "a before test = $a"
[ a -gt 10 ]
do
echo "a after test = $a"
a=$(($a-1))
done
echo "done"
isがechoより前の最後のコマンドである場合、do
doが受け取った終了コードは常にtrue(0)であり、ループは無限になります。
答え3
ここにある他の答えが暗示していますが、明示的に言及しないのは、これが組み込ま[
れているということです。注文する、お問い合わせ文法部分ではありませんwhile
。
help [
コマンドラインに次のように入力します。
[
:[
arg...]
条件式を評価します。これは「test」組み込み関数の同義語ですが、最後の引数はmatchで始まる
リテラルでなければなりません。]
[
だからあなたのスクリプトは正確にように:
!/bin/bash
a=12
while test $a -gt 10
do
echo "$a"
a=$(($a-1))
done
echo "done"
次に変更します。
!/bin/bash
a=12
while test $a -gt 10; echo something
do
echo "$a"
a=$(($a-1))
done
echo "done"
答え4
(他の回答を補うための注意事項)
条件リストで複数のコマンドを使用することは、Cと同様のループを実装するためによく使用されますdo { blah; blah; } while (condition)
。ここで、条件はループの終わりでチェックされ、ループのコードが複数回実行されます。
では、sh
次のことができます。
while
blah
blah
condition
do
continue # or :
done
次のような他の方法も可能である。
while true; do
blah
blah
condition || break
done
または:
continue=true
while "$continue"; do
blah
blah
condition || continue=false
done
end=false
until "$end"; do
blah
blah
condition || end=true
done