web-dev-qa-db-ja.com

cronjobを2日間設定する方法は?

Cronjobを使用してデータベースのバックアップを作成します。

バックアップは2日ごとに実行する必要があります。次のcronエントリを使用できますか?

0 0 2 * * * backup-command

これが間違っている場合は、cronを2日間設定する正しいコマンドを教えてください。

36
someone

ここ から:

Cronは「ステップ」値もサポートしています。

Domフィールドの*/2の値は、コマンドが2日ごとに実行されることを意味し、同様に、時間フィールドの*/5は、コマンドが5時間ごとに実行されることを意味します。例えば.

* 12 10-16/2 * * root backup.sh

と同じです:

* 12 10,12,14,16 * * root backup.sh

だからあなたは0 0 */2 * *が欲しいと思う。

取得したもの(0 0 2 * *)は、毎月​​2日の午前0時にコマンドを実行します。

pS回答に余分なアスタリスクが含まれているようです。形式は次のとおりです。

minute hour dom month dow user cmd

したがって、追加のアスタリスクはuserフィールドにあります。それは意図されていますか?

65
Dominic Rodger

免責事項:これは私のdeleted回答 ここ のコピーです。私はこの質問はもっとcanonicalだと思います、そして私の答えはここによりよく合います。

この質問を解釈する方法は2つあります。

  • 月に2日ごとにcronジョブをスケジュールしたいと思います。
  • 2日ごとにcronジョブをスケジュールしたいと思います。

1か月の日数のため、これらは2つの完全に異なるケースです。

Cronジョブを毎月2日ごとにスケジュールしたいと思います。

このために、範囲とステップ値の定義を組み合わせて使用​​します。

man 5 crontabステップ値は範囲と組み合わせて使用​​できます。 /<number>で範囲を続けると、範囲全体で数値の値をスキップすることを指定します。たとえば、「時間」フィールドで0-23/2を使用して、1時間おきのコマンド実行を指定できます(V7標準では0,2,4,6,8,10,12,14,16,18,20,22)。アスタリスクの後にステップ値も許可されるため、2時間ごとに実行するジョブを指定する場合は、*/2を使用できます。

次の例を参照してください。

# Example of job definition:
# .-------------------- minute (0 - 59)
# |  .----------------- hour (0 - 23)
# |  |  .-------------- day of month (1 - 31)
# |  |  |      .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |      |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |      |  |
# *  *  *      *  *   command to be executed
  0  0  */2    *  *   command1
  0  0  2-31/2 *  *   command2
  *  *  */2    *  *   command3
  • command1は、奇数日ごとの00:00に実行されます(ステップ2のデフォルト範囲、つまり1,3,5,7、...、31)
  • command2は、すべての偶数日の00:00に実行されます(つまり、2、4、6、8、...、30)。
  • command3はよくある間違いです。これは、すべての奇数日の1分ごとに実行されます。

注:このアプローチでは、command1が1月31日と2月1日(連続する2日間)の両方で実行されることを理解する必要があります

注:このアプローチでは、command2は1月31日と2月1日の両方をスキップし、3日後にのみ実行されることを理解する必要があります。

2日ごとにcronジョブをスケジュールしたい(X日から開始)

ここでもっと面白くなります。上記のメモはすでに、奇数の日数を持つ月の問題を示していました。

簡単に考える方法は、年間通算日を評価することです。

% date -d "2018-01-31" '+%j'
031
% date -d "2018-02-01" '+%j'
032

奇数か偶数かを簡単に調べることができます。ただし、これを行うと、共通の年(365日、うるう年は366日)の12月31日と1月1日に再び問題が発生します。これは、特定の日の継続的なカウンターがある場合に解決できます。 UNIXタイムスタンプを入力します。1970-01-01 00:00:00 UTCからの合計秒数です。

% date -d "2018-12-31" '+%s %j'                                                                                                                                                                                                               
1546214400 365
% date -d "2019-01-01" '+%s %j' 
1546300800 001
% date -d "2019-12-31" '+%s %j'                                                                                                                                                                                                               
1577750400 365
% date -d "2020-01-01" '+%s %j'                                                                                                                                                                                                               
1577836800 001

Cronjobがcommand4で2日おきにのみ00:00で、command500:00で「2018-03-14」から開始する場合、crontabは次のようになります。この:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
  0  0  *  *  *   daytestcmd 2 && command4
  0  0  *  *  *   daytestcmd 3 20180314 && command5

daytestcmdを次のように定義

#!/usr/bin/env bash
# get start time in seconds
start=$(date -d "${2:-@0}" '+%s')
# get current time in seconds
now=$(date '+%s')
# get the amount of days (86400 seconds per day)
days=$(( (now-start) /86400 ))
# set the modulo
modulo=$1
# do the test
(( days >= 0 )) && (( days % modulo == 0))

備考:UNIX時間はUTCで与えられます。 cronが夏時間の影響を受ける別のタイムゾーンで実行されている場合は、2時と3時の間にコマンドを実行しないことをお勧めします。これは、コマンドをスキップするか、コマンドを2回実行する可能性があります(時間が前後にジャンプするかによって異なります)

備考:UNIX時間はうるう秒の影響を受けません

8
kvantour