web-dev-qa-db-ja.com

日曜日を除く月の最初の日のcronjob

私のcrontabにそのようなエントリがあります:

0 0 1-2 * 1-6

月曜日から土曜日までの月の1日または2日の00:00に実行されるというのは正しいですか?たとえば、1日目が日曜日になると、実行されませんよね?ただし、日曜日ではないため、代わりに月の2日目にcronジョブを実行します。

2
Alexander Kim

月の最初の日が日曜日の場合、実際に実行されます。

その理由は、「日」(3番目のフィールド)と「曜日」(5番目のフィールド)の2つの条件がAND(両方とも発生する必要がある)ではなく、OR (どちらかが発生する必要があります)_man 5 crontab_から:

注:コマンドの実行日は、曜日と曜日の2つのフィールドで指定できます。両方のフィールドが制限されている場合(つまり、*でない場合)、いずれかのフィールドが現在の時刻と一致したときにコマンドが実行されます。たとえば、「30 4 1,15 * 5」を指定すると、毎月1日と15日、および毎週金曜日の午前4時30分にコマンドが実行されます。

したがって、cronジョブは毎月1日と2日およびさらに毎週月、火の深夜に実行されます。 、月の水、木、金、土。

コメントを書き込むときに、コマンドを月に1回だけ実行する必要があり、日曜日には実行する必要がない場合は、コマンド自体で日付を確認する必要があります。

コマンドを実行するための条件は次のとおりです。

_IF (date is 1st day of month AND date is not Sunday) 
    OR (date is 2nd day of month AND yesterday was Sunday) 
THEN run command
_

2つのcronジョブを作成できます。

_0 0 1 * * test $(date +\%u) -eq 7 || echo "today's the 1st day of the month but not Sun"
0 0 2 * * test $(date +\%u) -eq 1 && echo "today's Mon (=yesterday was Sun) and the 2nd day of the month"
_

最初のcronジョブは、毎月1日の深夜に実行されます。

  • _date +%u_は、1が月、2が火などの整数を返します(crontabでは「%」は エスケープ である必要があります)。

  • testは、$(date +%u1)が_7_(日曜日)と等しいかどうかをチェックします。

  • _||_はOR boolean 演算子であり、前のコマンドの戻り値に反応します。testがFALSEを返す場合、残りはFALSEを返します。コマンドのが実行されます。

2番目のcronジョブは、毎月2日深夜に実行されます。

  • ここでも、_date +%u_は整数を返します。ここで、1は月、2は火などです。

  • testは、$(date +%u1)が_1_(月曜日)と等しいかどうかをチェックします。

  • _&&_はAND boolean 演算子であり、testがTRUEを返す場合、コマンドの残りの部分が実行されます。

5
jaume