毎月第1月曜日にcronジョブを実行しますか?


32

毎月第一月曜日に8.30でcronからジョブを実行したいと思います。cron Wikipediaページには

時間/日付指定フィールドは、すべての現在の時刻と日付が一致したときに正常にジョブが実行されている間、一つの例外があります:両方の「月の日」と「曜日」が制限された(ではない「*」)されている場合は、どちらか「月の日」フィールド(3)または「曜日」フィールド(5)は、現在の日と一致する必要があります。

(私の強調)

それは、月の最初の月曜日ができず、月の最初の(または何でも)しかできないということですか?私はそれを回避する方法を考えることができません。


slhck-それは良い解決策のように聞こえますが、完全なコードで答えに拡張してくれませんか?それから私はそれを正しいとマークします:)
マックスウィリアムズ

回答:


39

条件を実際のcrontabコマンドに含めることができます。

[ "$(date '+%a')" = "Mon" ] && echo "It's Monday"

これで、この条件が月の最初の7日間のいずれかに当てはまる場合、最初の月曜日になります。ただし、crontabでは、パーセント構文をエスケープする必要があることに注意してください。

0   12  1-7 *   *   [ "$(date '+\%a')" = "Mon" ] && echo "It's Monday"

echoコマンドを、実行する実際のコマンドに置き換えます。私も同様のアプローチを見つけました。


実際、shlck、私はあまりにも早く話しました-これは私のcrontabでは機能しません:何らかの理由で日付テストに問題があるようです。これはコマンドラインで[ "$(date '+%a')" = "Mon" ] && echo "It's Monday"も機能[ $(date '+%a') = "Mon" ] && echo "It's Monday" しますが、crontabではこのテストで失敗しているようです。cronから有用なフィードバックを得ることもできません。[ "$(date '+%a')" = "Tue" ] >> /home/deploy/cron.log 2>&1エラー出力をログにキャプチャしようとしていますが、どちらでも機能していません:/
Max Williams

ふむ date出力が正しいかどうかを確認できますか?たとえば、cronこれをファイルに出力するコマンドを実行します。– date '+%a' > ~/datetest 2>&1次に、比較対象の文字列が正しいかどうかを確認します。
-slhck

1
問題が見つかりました+%a-crontabにあるときに必要なエスケープの割合、つまり、次の行が必要です [ "$(date '+\%a')" = "Mon" ] && echo "It's Monday"。あなたがあなたの答えを更新することができれば、それは将来の読者に役立つでしょう:)再びありがとう-マックス
マックスウィリアムズ

ああ、今ではその理由がわかります。動作するようになりました。試してくれてありがとう!
-slhck

14

私はスペイン語のロケールを持つコンピューターを持っているので、monlunに変更されるため、このアプローチは私には機能しません

他の言語も同様に失敗するため、言語の障壁を取り除く受け入れられた答えにわずかなバリエーションを加えました。

 0 9 1-7 * *   [ "$(date '+\%u')" = "1" ] && echo "¡Es lunes!"

+1¡ミュービエン、セニョール!
JakeGould

1
グラシアス¡ ; D
cumanacr

これは受け入れられた答えでなければなりません。私はオランダ語のロケールを持っていますが、これも平日に異なる名前を使用しています。また、文字列を比較して曜日を決定するよりも、数字を使用するほうがわかりやすいです。
0ne_Up

7

私は、日番号を処理する必要がないとき、それがより簡単であるとわかります。

月の最初の月曜日に実行:

0 2 * * 1 [ `date '+\%m'` == `date '+\%m' -d "1 week ago"` ] || /path/to/command

つまり、1週間前の月が現在の月と同じでない場合、その月の1日目(=月曜日)になります。

同様に、第三金曜日

0 2 * * 6 [ `date '+\%m'` == `date '+\%m' -d "3 weeks ago"` ] || /path/to/command

つまり、3週間前の月が現在の月と異なる場合、その月の3日目(=金曜日)になります


週の6日目は金曜日ではなく土曜日です。
ロバート

4

次のように、毎月第4月曜日の午後4時に実行するジョブをスケジュールしました。

0 16 22-28 * Mon [ "$(date '+\%a')" == "Mon" ] && touch /home/me/FourthMonOfMonth.txt

1

私の知る限り、crontabのみを使用することはできませんが、ラッパー関数を使用して、「月の最初の7日間」のcontabエントリから正しい日を選択できます。エントリからこれを参照してください。

ラッパースクリプトは

#! /usr/bin/ksh
day=$(date +%d)
if ((day <= 7)) ; then
   exec somecommand
fi
exit 1

crontabエントリを使用して、それを実行する必要があります(wrapper.shと呼ばれ、グローバルに利用可能な場合)

0 0 * * 1 wrapper.sh

ありがとうエレマキ。タスク内で実行される追加のコードを使用して、スクリプト内で月の最初の月曜日かどうかをテストし、crontabで月曜日ごとに呼び出すことで、同様のソリューションを考えました。ルビースクリプトなので、週の曜日を簡単にテストできます。しかし、私はcrontabのみの方法があることを望んでいた。
マックスウィリアムズ

1

Solaris 10では、次のように条件をフォーマットする必要がありました。

[ `date +\%a` = "Sat" ] && echo "It's Saturday"

1

月の最初の7日間はcronjobを実行して、月曜日にのみ実行することができます。

30 8 * * 1 [`date +\%d` -le 07] && <job>

上記はあなたのために働くはずです。


最初の週に実行し、月曜日に確認するために、成功ヒット率を1つ増やします。:-)
xmedeko

1

使用することをお勧めします

"$(/bin/date '+%\w')" = "1"

の代わりに

"$(date '+\%a')" = "Mon"

ロケールの問題を回避するため。


0

私はこの種の問題の一般的な解決策を作りました。それは月の最後の平日、最初、2番目、3番目…に有効です。

次のように使用できます。

30 06 * * Mon run-if-today 1 "Mon" && echo "First Monday"
30 06 * * Thu run-if-today 3 "Thu" && echo "Third Thursday"
30 06 * * Sun run-if-today L "Sun" && echo "Last Sunday"

スクリプトは、曜日と目的の曜日の両方の日付範囲をチェックし、両方が一致する場合は0を返し、そうでない場合は1を返します。

ここでコードを確認してください。https://github.com/xr09/cron-last-sunday


0

私はこれが問題をよりエレガントに解決すると信じています:

30 8 1-7 * 1 /run/your/job.sh

1
ドッ!:「両方のフィールドが制限されている(つまり、*ではない)場合、いずれかのフィールドが現在の時刻と一致したときにコマンドが実行されます。」
symcbean 14

また、2月(28日で終了する日)には、4年ごとに実行されることはありません。
-igraczech

「どちらか」は「両方」ではなく、いずれかを意味します。これは、月の最初の7日間毎日実行されます。
minusf

この行は、各月の第七の最初だけでなく、毎週月曜日の上でコマンドを実行します
トマシュヤクブRupの

0

私はphpとjsを使用してcronステートメントを解釈するため、bashを使用できません。最後に、cronだけで実際に可能であることわかりました。

0 30 8 * 1/1 MON#1

これが他の誰かに役立つことを願っています。とにかく、私はあなたにすべての美しい日を願っています。:-)


これは、それはおそらく石英だ、cronのではありません
sivann

-1
0 9 1-7 * 1 * 

これは、毎月の月曜日ごとに機能します。


回答が受け入れられました。新しいバージョンであなたの回答がより良い、異なる、または有用である、など
mic84
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.