web-dev-qa-db-ja.com

Bashでdo-whileループをエミュレートする

Bashでdo-whileループをエミュレートする最良の方法は何ですか?

whileループに入る前に条件をチェックし、ループ内の条件の再チェックを続けることもできますが、それはコードが重複しています。よりクリーンな方法はありますか?

私のスクリプトの擬似コード:

while [ current_time <= $cutoff ]; do
    check_if_file_present
    #do other stuff
done

これは、check_if_file_present時間の後に起動された場合、$cutoffを実行しません。

111
Alex

2つの簡単なソリューション:

  1. Whileループの前にコードを1回実行します

    actions() {
       check_if_file_present
       # Do other stuff
    }
    
    actions #1st execution
    while [ current_time <= $cutoff ]; do
       actions # Loop execution
    done
    
  2. または:

    while : ; do
        actions
        [[ current_time <= $cutoff ]] || break
    done
    
184
jm666

ループの本体をwhileの後、テストの前に配置します。 whileループの実際の本体はノーオペレーションでなければなりません。

while 
    check_if_file_present
    #do other stuff
    (( current_time <= cutoff ))
do
    :
done

コロンの代わりに、continueを使用すると、読みやすくなります。また、echo "Retrying in five seconds"; sleep 5などのbetweenの反復のみを実行するコマンドを挿入することもできます(最初の前または最後の後ではありません)。または、値の間の区切り文字を印刷します。

i=1; while printf '%d' "$((i++))"; (( i <= 4)); do printf ','; done; printf '\n'

整数を比較しているように見えるので、二重括弧を使用するようにテストを変更しました。二重角括弧内では、<=などの比較演算子は字句的であり、たとえば2と10を比較するときに間違った結果を返します。これらの演算子は、単一の角括弧内では機能しません。

126

コロンの代わりに、読みやすいと思う場合はcontinueを使用できます

このメソッドは、私が探していたDo-Whileループの実行方法を模倣しています。アクションの後に条件テストを行います。また、continueステートメントの代わりに、doステートメントの後に(必要に応じて)インデックスインクリメントを配置できることもわかりました。

while 
    check_if_file_present
    #do other stuff
    (( current_time <= cutoff ))
do
    (( index++ ));
done
6
Randyman99