web-dev-qa-db-ja.com

毎月第1日曜日に実行するようにスケジュールする方法

RedHatでBashを使用しています。毎月第1日曜日の午前9時にcronジョブを実行するようにスケジュールする必要があります。これどうやってするの?

49
ring bearer

次のようなものをcrontabファイルに入れることができます:

00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script

date +%dは、現在の日付の番号を提供し、その日付が7以下であるかどうかを確認できます。7以下であれば、コマンドを実行します。

このスクリプトを日曜日にのみ実行する場合、月の最初の日曜日にのみ実行されることを意味する必要があります。

crontabファイルでは、dateコマンドのフォーマットオプションをエスケープする必要があることに注意してください。

130
Lukasz Stelmach

次の2つのアプローチを組み合わせる必要があります。

a)cronを使用して、毎週日曜日の午前9時にジョブを実行します。

 00 09 * * 7     /usr/local/bin/once_a_week

b)once_a_weekの先頭で、日付を計算し、Shell、Python、C/C++、...を使用して月の日を抽出し、1〜7の範囲内でテストします。その場合、実際のスクリプトを実行します。そうでない場合は、静かに終了します。

12

この問題に対する最も明白なアプローチのように見えるものがnot動作することは注目に値します。

次のように、曜日を0(日曜日)に、曜日を1〜7に指定するcrontabエントリを書くことができると思うかもしれません。

# This does NOT work.
0 9 1-7 * 0 /path/to/your/script

...しかし、 Cronが曜日と曜日の両方が指定されたcrontab行を処理する方法の偏心 のため、これは機能せず、実際に実行されます月の1日、2日、3日、4日、5日、6日、7日(週の曜日に関係なく)andonevery月の日曜日。

date[ ... ]チェックを使用してこのようなルールを設定することをお勧めします-crontabで曜日を指定して [ および date は、スクリプトを実行する前に、 受け入れられた回答 =、またはcrontabで月の範囲を指定し、[およびdateを使用して、実行前に曜日を確認します。次のようになります。

# This DOES work.
0 9 1-7 * * [ $(date +\%u) = 7 ] && /path/to/your/script

Crontab行を使用しているOSに関係なく動作することを確認したい場合に留意すべきいくつかのベストプラクティス:

  • 比較には、=ではなく==を使用します。すべてのシェルが[演算子をサポートする==の実装を使用するわけではないため、より移植性があります。
  • %u指定子をdateに使用して、%a演算子ではなく、曜日を数値として取得します。これは、%aがロケールに応じて異なる結果を与えるためですdateは実行中です。
  • dateユーティリティはシステムによって異なる場所にあるため、/bin/date/usr/bin/dateではなく、dateを使用してください。
6
Mark Amery

ハッキングソリューション:cronジョブを毎週日曜日に実行しますが、スクリプトで開始日を確認し、月の日付が7を超える場合はすぐに終了します...

5
thesunneversets

Cronタスクを実行します。最初の月曜日、3番目の火曜日、最後の日曜日、何でも..

http://xr09.github.io/cron-last-sunday/

run-if-todayスクリプトをパスに追加し、cronで使用します。

30 6 * * 6 root run-if-today 1 Sat && /root/myfirstsaturdaybackup.sh

run-if-todayスクリプトは、正しい日付である場合にのみ0(Trueの場合はbash値)を返します。

編集:

シンプルなインターフェースで、週番号に1つのパラメーターのみが追加されました。

# run every first saturday
30 6 * * 6 root run-if-today 1 && /root/myfirstsaturdaybackup.sh

# run every last sunday
30 6 * * 7 root run-if-today L && /root/lastsunday.sh
5
MGP

これは平日の名前でも機能します:

_0 0 1-7 * * [ "$(date '+\%a')" == "Sun" ] && /usr/local/bin/urscript.sh
_

しかし、

[ "$(date '+\%a')" == "Sun" ] && echo SUNDAY

crontabでの「%」の特別な処理のためにコマンドラインで[〜#〜] fail [〜#〜]https://stackoverflow.com/a/3242169/2919695

4
maniac_on_moon

Cronで毎日または毎週日曜日にcronでジョブを実行したくない場合は、コードを実行するラッパーを作成し、次の最初の日曜日を決定し、その日に実行するようにスケジュールできます。

次に、そのラッパーを月の次の最初の日曜日にスケジュールします。その後、すべてを処理します。

コードは次のようになります(何かに重点を置いて...エラーチェックは行われません):

#! /bin/bash
#We run your code first
/path/to/your/code
#now we find the next day we want to run
nskip=28 #the number of days we want to check into the future
curr_month=`date +"%m"`
new_month=`date --date='$nskip days' +"%m"`
if [[ curr_month = new_month ]] 
then
((nskip+=7))
fi
date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler
#schedule the job using "at"
at -m $date < /path/to/wrapper/code

ロジックは、次の最初の日曜日を見つけるのは簡単です。現在の月の最初の日曜日に開始するため、28を追加すると、現在の月の最後の日曜日または翌月の最初の日曜日に配置されます。現在の月である場合、次の日曜日(翌月の最初の週になります)に増分します。

そして、「at」を使用しました。それが不正行為かどうかはわかりません。しかし、主なアイデアは次の最初の日曜日を見つけることです。ジョブを実行したい日付と時刻がわかっているので、その後はどんなスケジューラーでも代用できます(ただし、別のスケジューラーでは日付の構文が異なる場合があります)。

0
user390948

cron.hourlyを使用して別のスクリプトを呼び出すこともできます。そのスクリプトは、月の最初の日曜日で午前9時かどうかを確認し、そうであればプログラムを実行します。私にとって十分に最適な音:-)。

0
gtrak