[Raspberry Pi] cron で「第 X 曜日の前日」に実行

私はゴミの日を忘れないために、いつも Raspberry Pi から Slack に通知をしている。

[Raspberry Pi] シェルスクリプトで Slack に投稿する – with a Christian Wife
https://wacw.cf/2018/03/04/posting-slack-with-shell-script-on-pi/

毎週火曜日の可燃ゴミの通知をするといったことは簡単にできる。

問題は月一の古紙回収日だ。わが家の地区の月一の古紙回収日は第3土曜日だ。

第3土曜日に通知するといったことは、以下のページを参考にすればできた。

crontabで第?曜日にタスクを実行する方法 – ソフラボの技術ブログ
http://shinsuke789.hatenablog.jp/entry/2015/08/07/123000

すなわち、第3土曜日の6時 50 分に通知するなら、以下のように cron に書けばいい。

50 6 15-21 * * [ "$(date '+\%w')" -eq 6 ] && [処理内容]

でも古紙回収の性質上、前日にゴミ出しの準備をしたい。段ボールをまとめたり、牛乳パックを崩したりしなくてはいけない。だから「第3土曜日の “前日” 」に通知したいのだ。「明日は古紙回収日です。」と前日に Slack に通知したい。

そんなの簡単。第3金曜日に通知すればいい__と思って通知していたら罠がありました。土曜日から始まる月に関しては、第3土曜日の前日は第2金曜日なのだ。第3金曜日に通知したら1週間後になってしまう! 実際このせいでゴミ出しをし忘れたことがある。そして今月がまさに土曜日から始まる月なのだ(偶然今月はそれに気づいてゴミ出しができた)。

月一のゴミ出しをし忘れたら、1ヶ月待たなくてはならないので面倒なことになる(Amazon の大量の段ボールなどはすぐ捨てたい)。

「第3土曜日の前日」に通知する方法をいろいろネットで調べてみた。日本語のページで見つからず、海外のページも探した(Raspberry Pi は海外の情報の方がたくさんある)。以下のフォーラムでも議論されているが、ゴチャゴチャいろいろプログラムを組んだりしている人がいるわりに、有益な方法を見つけられなかった。

How to run a cron job the day before the 1st Wednesday of every month? – Setup, Configuration and Use / Scripts & Rules – openHAB Community
https://community.openhab.org/t/how-to-run-a-cron-job-the-day-before-the-1st-wednesday-of-every-month/49058/15

しかし、ふと天才的な閃きをしました!

それはカレンダーを見ていて気付いた。土曜日から始まる月は、第3土曜日の前日が必ず 14 日になるのだ。こんなシンプルなことだけど、これを利用すれば cron で簡単に対応できる。すなわち、14 日が金曜日となる日だけ処理を実行すればいいのだ。

20181216_093847

cron で 14 日が金曜日に実行するには以下。

50 6 14 * 5 [処理内容]

その他の月は第3金曜日に通知すればいいが、土曜日から始まる月を除外するため、第3金曜日( 21 日)を除けばいいのだ(第3週は 15-21 だが、15-20 にする)。これで土曜日から始まる月に2重に通知が来ることもない。

50 6 15-20 * * [ "$(date '+\%w')" -eq 5 ] && [処理内容]