web-dev-qa-db-ja.com

次の実行までの残り時間

Cronスケジュールで特定のジョブの次の実行の残り時間を計算する必要があります。1時間に1日3回などの頻度のジョブがあるCronがあります。特定の日/日付に実行されているジョブがないため、HHのみです。 MM:SSが関係しています。また、RHELで_/var/spool/cron/_を確認する権利がありません。一部のジョブが_9:30_で始まる場合、

30 9 * * * /some/job.sh
-bash-3.2$日付+ "%H:%M" 
13:52

_19 Hours and 38 Minutes_として出力する必要があります。現在のシステム時刻から次の実行が行われるまでの合計時間を知るにはどうすればよいですか?秒の計算は、ジョブ時間の前後でのみ考慮されます。

7
Keyshov Borate

cronは、ジョブがいつ起動されるかわかりません。毎分、すべてのcrontabエントリを調べ、"$(date '+%M %H %d %m %w')"に一致するエントリを起動します。

あなたができることは、今から49時間後までのすべてのタイムスタンプを今から49時間(DSTの変更を考慮に入れて)生成し、手作業で照合を行い(トリッキーな部分)、最初に一致したものを報告することです。

または、 croniterpythonモジュールを使用できます。

python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("3 9 * * *", datetime.now())
print iter.get_next(datetime)'

遅延について:

$ faketime 13:52:00 python -c '
from croniter import croniter
from datetime import datetime
d = datetime.now()
iter = croniter("30 9 * * *", d)
print iter.get_next(datetime) - d'
19:37:59.413956

ただし、DSTの変更に関する潜在的なバグに注意してください。

$ faketime '2015-03-28 01:01:00' python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("1 1 * * *", datetime.now())
print iter.get_next(datetime)'
2015-03-29 02:01:00

$ FAKETIME_FMT=%s faketime -f 1445734799 date
Sun 25 Oct 01:59:59 BST 2015
$ FAKETIME_FMT=%s faketime -f 1445734799  python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("1 1 * * *", datetime.now())
print iter.get_next(datetime)'
2015-10-25 01:01:00

$ FAKETIME_FMT=%s faketime -f 1445734799 python -c '
from croniter import croniter
from datetime import datetime
d = datetime.now()
iter = croniter("1 1 * * *", d)
print iter.get_next(datetime) - d'
-1 day, 23:01:01

cron自体は、時間が後戻りした場合にジョブを2回実行することを避け、時間の進みの場合はシフト後にスキップされたジョブを実行することを避けます。

9

それが起こると%T組み込みのprintfの形式ksh93シェルは、入力としてcrontab仕様をサポートしています。

$ ksh93 -c 'printf "%(%F %T)T\n" now "30 9 * * *"'
2017-11-07 17:06:41
2017-11-08 09:30:00

したがって、次のコマンドでデルタを数秒で取得できます。

#! /bin/ksh93
crontab_line='30 9 * * *'
delta=$(($(printf '(%(%s)T - %(%s)T) / 60' "$crontab_line" now)))
echo "Next run in $((delta/60)) hours and $((delta%60)) minutes."
3