RedHatでBashを使用しています。毎月第1日曜日の午前9時にcronジョブを実行するようにスケジュールする必要があります。これどうやってするの?
次のようなものをcrontab
ファイルに入れることができます:
00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script
date +%d
は、現在の日付の番号を提供し、その日付が7以下であるかどうかを確認できます。7以下であれば、コマンドを実行します。
このスクリプトを日曜日にのみ実行する場合、月の最初の日曜日にのみ実行されることを意味する必要があります。
crontab
ファイルでは、date
コマンドのフォーマットオプションをエスケープする必要があることに注意してください。
次の2つのアプローチを組み合わせる必要があります。
a)cron
を使用して、毎週日曜日の午前9時にジョブを実行します。
00 09 * * 7 /usr/local/bin/once_a_week
b)once_a_week
の先頭で、日付を計算し、Shell、Python、C/C++、...を使用して月の日を抽出し、1〜7の範囲内でテストします。その場合、実際のスクリプトを実行します。そうでない場合は、静かに終了します。
この問題に対する最も明白なアプローチのように見えるものが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
を使用してください。ハッキングソリューション:cronジョブを毎週日曜日に実行しますが、スクリプトで開始日を確認し、月の日付が7を超える場合はすぐに終了します...
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
これは平日の名前でも機能します:
_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 )
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」を使用しました。それが不正行為かどうかはわかりません。しかし、主なアイデアは次の最初の日曜日を見つけることです。ジョブを実行したい日付と時刻がわかっているので、その後はどんなスケジューラーでも代用できます(ただし、別のスケジューラーでは日付の構文が異なる場合があります)。
cron.hourlyを使用して別のスクリプトを呼び出すこともできます。そのスクリプトは、月の最初の日曜日で午前9時かどうかを確認し、そうであればプログラムを実行します。私にとって十分に最適な音:-)。