シェルスクリプトのwhileとdoの間

シェルスクリプトのwhileとdoの間

うまく動作する次のスクリプトがあります。

!/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より前の最後のコマンドである場合、dodoが受け取った終了コードは常に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

関連情報