毎週火曜日の特定の時間に実行される cron を介してジョブを実行したいと思います。毎週火曜日は簡単です:
0 6 * * Tue
しかし、「隔週火曜日」(または、隔週) に作成するにはどうすればよいでしょうか。スクリプト自体にロジックを実装したくはありませんが、定義はcronでのみ保持します。
毎週火曜日の特定の時間に実行される cron を介してジョブを実行したいと思います。毎週火曜日は簡単です:
0 6 * * Tue
しかし、「隔週火曜日」(または、隔週) に作成するにはどうすればよいでしょうか。スクリプト自体にロジックを実装したくはありませんが、定義はcronでのみ保持します。
火曜日の cron ロジックを変更して、エポックから隔週で実行するようにします。
1 週間が 604800 秒であることを知り (DST の変更と閏秒を無視します、ありがとうございます)、GNU 日付を使用します。
0 6 * * Tue expr `date +\%s` / 604800 \% 2 >/dev/null || /scripts/fortnightly.sh
カレンダーの計算はイライラします。
@xahtepの答えは素晴らしいですが、@Doppelgangerがコメントで指摘したように、特定の年の境界で失敗します。date
ユーティリティの「年の週」指定子はどれもここでは役に立ちません。1 月上旬のある火曜日は、必然的に前年の最終火曜日の週パリティを繰り返します: 2016-01-05 (%V)、2018-01-02 (%U)、および 2019-01-01 (%W) .
これはどうですかcrontab
、最初の 5 つのフィールドで正確に定義されていなくても、保持されます。
0 6 * * Tue expr `date +\%W` \% 2 > /dev/null || /scripts/fortnightly.sh
少しばかげているかもしれませんが、第 1 火曜日ごとに 1 つ、第 3 火曜日ごとに 1 つの 2 つの cron ジョブを作成することもできます。
最初の cronjob:
0 0 8 ? 1/1 TUE#1 *
2 番目の cronjob:
0 0 8 ? 1/1 TUE#3 *
ここでの構文についてはよくわかりませんが、http://www.cronmaker.com/を使用してこれらを作成しました。
@xahtep と @Doppelganger は、
%W
上記の特定の年の境界で使用する問題について議論しました。@pilcrowの答えはこれをある程度回避しますが、特定の境界では失敗します。このトピックやその他の関連トピックの回答では、1 日 (対 1 週間) の秒数が使用されますが、これも同じ理由で特定の境界で失敗します。
これは、これらのアプローチが UTC 時間 (日付 +%s) に依存しているためです。毎週第 2 火曜日の午前 1 時と午後 10 時にジョブを実行する場合を考えてみましょう。
GMT-2 を仮定します。
1 日に 1 回だけチェックする場合、これは問題にはなりませんが、複数回チェックする場合、または UTC 時間に近づいていてサマータイムが発生している場合、スクリプトはこれらを日付とは見なしません。同日。
これを回避するには、UTC ではなくローカルタイムゾーンに基づいて UTC からのオフセットを計算する必要があります。BASH でこれを行う簡単な方法が見つからなかったので、Perl でクイック ワンライナーを使用して UTC からのオフセットを数秒で計算するソリューションを開発しました。
このスクリプトは、ローカル タイムゾーンを出力する date +%z を利用します。
TZ_OFFSET=$( date +%z | perl -ne '$_ =~ /([+-])(\d{2})(\d{2})/; print eval($1."60**2") * ($2 + $3/60);' )
DAY_PARITY=$(( ( `date +%s` + ${TZ_OFFSET} ) / 86400 % 2 ))
次に、その日が偶数か奇数かを判別します。
if [ ${DAY_PARITY} -eq 1 ]; then
...
else
...
fi
第 2 週の毎週火曜日のみが必要な場合:
00 06 * * 2#2
構文 "/2" は、曜日には使用できません。したがって、上記のスマートに追加したのは、MonthDay フィールドで 1,15 を使用するだけです。
0 6 1,15 * * /scripts/fornightly.sh > /dev/null 2>&1
Cron は「1 つおき」の構文「/2」を提供します。適切な時間単位フィールドに「/2」を続けるだけで、「1 回おきに」cron ジョブが実行されます。あなたの場合...
0 6 * * Tue/2
上記は隔週火曜日に実行する必要があります。
なぜ次のようなものではないのですか
0 0 1-7,15-21,29-31 * 5
それは適切ですか?