ENV:GNU bash、バージョン4.2.46(2)-リリース(x86_64-redhat-linux-gnu)(以前)
- 各ループに同じ時間がかかることを望みます。
- 循環は決して止まらない
- この
api_call
機能が正常に実行されるまで約1秒〜5秒かかります。 - ネットワークの問題により、60秒のタイムアウトを超えるまでAPI呼び出しが中断されることはほとんどありません。
私のスクリプトA
TIMEFORMAT=%R
while true; do
time=$(date +'%F %T')
api_result=$( { time api_call; } 2>api_runtime.txt )
api_runtime=$(cat api_runtime.txt)
echo "${time} ${api_result}"
sleep (( 10 - ${api_runtime} ))
done
私はScrit Aがある日、ネットワークが遅くなり、ループが同期しなくなるまでタスクを実行すると思いました。
私のスクリプトB
TIMEFORMAT=%R
while true; do
time=$(date +'%F %T')
api_result=$( api_call & )
sleep 10
echo "${time} ${api_result:-No response}"
done
api_call
スクリプトBも現在動作しているようですが、次のループが10秒以上かかると安全であるかどうかはわかりません。
どうやってこれを達成できますか?
ベストアンサー1
コマンドオーバーライド内でこれを使用すると、デフォルトのスクリプト&
と同時にバックグラウンドでコマンドが実行されず、コマンドオーバーライドで何も起こりません。
$ time str=$( (sleep 2; echo hello) & )
real 0m2.006s
user 0m0.000s
sys 0m0.003s
$ echo "$str"
hello
上記の操作は、以下の作業と同様に完了する前に2秒間中断されます。
$ time str=$( echo hello & sleep 2; echo bye )
real 0m2.011s
user 0m0.000s
sys 0m0.006s
$ echo "$str"
hello
bye
sleep 10
これは、ループ本体の実行時間に常に10秒を追加する必要はないことを意味します。これは、前の行の割り当てが実行されるまでブロックされ、api_call
終了時に発生するためです。
各ループの反復に60秒をかかるようにするには(緊急タイムアウト長さ):
while true; do
result=$( sleep 60 & api_call )
done
api_call
これにより、戻り時間がそれより短い場合でも割り当てに60秒かかります。
または、
while true; do
result=$( sleep 10 & timeout 10s api_call )
done
api_call
...TERM信号が明示的に送信されるよりも遅い場合は10秒かかります。
長い間実行されているスクリプトであれば、徐々にドリフトすることを期待できます。考えられる解決策の1つは、cronジョブを使用して定期的にスケジュールを変更することです(実行中のスクリプトを終了して再実行)。