「4:00」のような特定の時間が次に発生するまでスリープする一連のコマンドまたは単一のコマンドが必要です。
どうすればいいですか?
at
コマンドまたはcronjobは、現在使用しているスクリプトを残してはいけないため、オプションではありません。
私が話している特定のケースは、画面で実行されるスクリプトです。スクリプトのある時点で必要な多くの重要な変数が格納されているため、スクリプト自体によるスクリプトの実行を停止しないことが非常に重要です。スクリプトは、常に通常の方法で実行されるとは限りません。特定の時間に実行する必要があるだけです。
スクリプトがファイルや、cronjobsや他の画面などの他のタスクを作成する必要がある場合は、非常に有益です。これは単にデザインの問題です。
私はちょうどいい考えを持っていました:
difference=$(($(date -d "4:00" +%s) - $(date +%s)))
if [ $difference -lt 0 ]
then
sleep $((86400 + difference))
else
sleep $difference
fi
もっと良いアイデアはありますか?
必要に応じて詳細が追加されます!
terdonの提案は機能しますが、私のほうが効率的です。
difference=$(($(date -d "4:00" +%s) - $(date +%s)))
if [ $difference -lt 0 ]
then
sleep $((86400 + difference))
else
sleep $difference
fi
これは、指定された時間と現在の時間の差を秒単位で計算しています。数が負の場合は、1日の秒数(正確には86400)を追加して、スリープする秒数を取得する必要があります。数が正数の場合は、そのまま使用できます。
それがシェルスクリプトであると仮定すると、これはうまくいくはずです:
while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done
それは24時間です。これを4:00 AMと4:00 PMの両方で続行する場合は、代わりにこれを使用します。
while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done
OpenBSDでは、次のコマンドを使用して_*/5
_ 5分 crontab(5)
を圧縮できます。 1時間ごとに_00
_ジョブを実行します(正確な間隔で同じタスクを実行しながら、生成される電子メールの数を減らすため):
_#!/bin/sh -x
for k in $(jot 12 00 55)
do
echo $(date) doing stuff
sleep $(expr $(date -j +%s $(printf %02d $(expr $k + 5))) - $(date -j +%s))
done
_
date(1)
も、最後の反復で sleep(1)
を意図的に壊すことに注意してください。 _60
_分は有効な時間ではないので(有効でない限り)、メールレポートを取得する前に余分な時間を待つ必要はありません。
また、繰り返しの1つに割り当てられた時間が5分を超える場合、sleep
も同様に、まったくスリープ状態にならないことにより、意図的に失敗します(コマンドラインオプションとして解釈される負の数が原因です)。 、次の1時間または永遠に循環するのではなく)、ジョブが割り当てられた時間内にまだ完了できることを確認します(たとえば、反復の1つだけが5分以上かかる場合でも、次の1時間に何も回り込むことなく、追いつく時間です。
printf(1)
が必要なのは、date
が分の指定に正確に2桁を期待しているためです。