各ループにまったく同じ時間がかかるようにするにはどうすればよいですか?

各ループにまったく同じ時間がかかるようにするにはどうすればよいですか?

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ジョブを使用して定期的にスケジュールを変更することです(実行中のスクリプトを終了して再実行)。

おすすめ記事