Cronを介してジョブを実行します。このジョブは、指定された時刻に毎週火曜日に実行されます。毎週火曜日は簡単です:
0 6 * * Tue
しかし、「2番目の火曜日」(またはお好みであれば-2週間ごと)にどうやって作るのでしょうか?スクリプト自体にロジックを実装したくありませんが、cronでのみ定義を保持します。
これについては、最初の5つのフィールドで正確に定義されていなくても、crontab
に保持されます。
0 6 * * Tue expr `date +\%W` \% 2 > /dev/null || /scripts/fortnightly.sh
火曜日のcronロジックを変更して、1週間おきに実行しますエポック以降。
週に604800秒があることを知って(DSTの変更とうるう秒を無視して、ありがとう)、GNU date:
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) 。
pilcrow's answer は素晴らしい。ただし、(エポック以降)毎週even週ごとにfortnightly.shスクリプトが実行されます。スクリプトをodd週に実行する必要がある場合は、彼の答えを少し調整できます。
0 6 * * Tue expr \( `date +\%s` / 604800 + 1 \) \% 2 > /dev/null || /scripts/fortnightly.sh
1を0に変更すると、数週間に戻ります。
ちょっと馬鹿げているかもしれませんが、2つのcronjobを作成できます。
最初の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日の秒数(対週)を使用しますが、これも同じ理由で特定の境界で失敗します。
これは、これらのアプローチがUTC時間(日付+%s)に依存しているためです。第2火曜日の午前1時と午後10時にジョブを実行している場合を考えます。
GMT-2の場合:
毎日1回だけチェックしている場合、これは問題になりませんが、複数回チェックしている場合、またはUTC時間に近く、夏時間が発生している場合、スクリプトはこれらをチェックしません同日。
これを回避するには、UTCではなくlocalタイムゾーンに基づいてUTCからのオフセットを計算する必要があります。 BASHでこれを行う簡単な方法が見つからなかったため、Perlのクイックワンライナーを使用してUTCからのオフセットを秒単位で計算するソリューションを開発しました。
このスクリプトは、ローカルタイムゾーンを出力する日付+%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
指定された開始日に基づいてそれを行いたい場合:
0 6 * * 1 expr \( `date +\%s` / 86400 - `date --date='2018-03-19' +\%s` / 86400 \) \% 14 == 0 > /dev/null && /scripts/fortnightly.sh
2018年3月19日から始まる隔週の月曜日に発砲する必要があります
式の読み取り:次の場合、月曜日の午前6時に実行.
1-今日の日付を秒単位で取得し、1日の秒数で割って日数エポックに変換します
2-開始日にも同じことを行い、エポック以降の日数に変換します
3-2つの違いを取得する
4-14で除算して残りを確認する
5-残りがゼロの場合、2週間サイクルです
3週間ごとはどうですか?
私の提案は次のとおりです。
0 6 * * Tue expr `date +\%W` \% 3 == 0 > /dev/null || /scripts/fortnightly.sh
...または...
0 6 * * Tue expr `date +\%W` \% 3 == 1 > /dev/null || /scripts/fortnightly.sh
...またはもちろん...
0 6 * * Tue expr `date +\%W` \% 3 == 2 > /dev/null || /scripts/fortnightly.sh
...週の回転に応じて。