私は次の解決策を使用しました。この回答私が書いているスクリプトではうまくいかないようです。バッシュ5を使用しています。これは単純化されたテストケースです。do_thing
関数は5分の倍数で呼び出されることを望んでいます(実際のスクリプトではメインプログラムの先頭でループをトリガーするため、$min
同じでない場合)、実行するとトリガーされます。これはMultiple + 1なので、明らかにどこかに1つずつ、または数学エラーが少ししか表示されません。どんなアイデアがありますか?$minutes
do_thing
#!/usr/bin/env bash
minutes=6
sec=00
min="$minutes"
do_thing() {
echo 'done thing'
}
while [ "$min" -ge 0 ]; do
remainder=$(( min % 5 ))
# TODO: this is broken
[ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ] && do_thing
while [ $sec -ge 0 ]; do
echo "$min $sec"
((sec=sec-1))
sleep 1
done
sec=59
((min=min-1))
done
答え1
set -x
Bashスクリプトをデバッグするときに最初にすべきことは、一番上に追加することです。これにより、スクリプトが実行する操作、ループの各反復で各テストの外観などを確認できます。
私が置く場所は次のとおりです。
#!/usr/bin/env bash
# NOTE: Remove or comment the below line when you're done debugging!
set -x
minutes=6
sec=00
...
デバッグ中にコード全体に分散させると、echo "myvar = $myvar"
スクリプトの主要ポイントで変数の値を追跡して、予想される値と比較できます。
論理の欠陥は、一度「分カウンタ」ループを終了できる条件を取得すると、すぐに最小値を1に減らします。したがって、残りを再計算すると、常に1つが減ります。 「カウンター」を減らしています今後希望の計算を実行するために使用されます!
論理的に秒= 0をテストしたいと思います。それから残りを計算し、それから次のループを設定します。
#!/usr/bin/env bash
#set -x
minutes=6
sec=00
min="$minutes"
do_thing() {
echo 'done thing'
}
while [ "$min" -ge 0 ]; do
while [ $sec -ge 0 ]; do
echo "$min $sec"
((sec=sec-1))
sleep 1
done
remainder=$(( min % 5 ))
# Added echo for debugging
echo "remainder = $remainder"
[ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ] && do_thing
sec=59
((min=min-1))
done
ここでまた目立つ点は――非常に&&
andに注意してください||
。高速で汚れた場合は問題ありませんが、複雑なロジックの場合はだますことができます!
これらの論理演算子はいいえ選択肢があるとしても、適切にテストしてください。時々- テストの使用との違いの1つは、if []; then...
終了コードを自動的に使用することです。注意深く読み、()
必要な作業順序を適用するために使用しないで、複数を連続して使用しないでください。
私のアドバイスを受け入れてここを避けたい場合は、&&
次の方法があります(ネストされた `if は別の方法ですが、必要でなければ使用しないことをお勧めします)。
...
remainder=$(( min % 5 ))
# Added echo for debugging
echo "remainder = $remainder"
if ([ "$remainder" -eq 0 ] && [ "$min" -ne "$minutes" ]); then
do_thing
fi
sec=59
((min=min-1))
...