Cronは祝日には実行したくない
こんにちは、クリエイティブSecの長谷川です。
(以下は長い前置きになりますが、さっさと方法を知りたいという方はここまでジャンプしましょう)
弊社では始業や終業、休憩時間の開始/終了時にチャイムを鳴らしていたり
BGMとして音楽の再生をしたりしています。
もともとこれらの再生は社内で使われていなかったiPhoneを再利用していたのですが
先日ついにそのiPhoneがお亡くなりになりました・・・。
そこで、同じく社内で使われていなかったシングルボードコンピュータ「Raspberry PI」を利用してチャイムや音楽を鳴らすようにしました。
操作用の端末がなくなったことによる問題
さて、今までは社内にiPhone端末が置かれていたので
音楽を再生/停止したい場合は誰かが操作してくれていました。
しかし、いきなりRaspberry PIに変わったことで
人によってはどうやって操作したらいいのか分からず
BGMが再生されない日が出てきました。
ちなみにWEBで接続して、コントロールパネルから音楽を再生したりすることができるようにしていたのですが
そもそもきちんとその方法を周知できていなかったり、また知っている人も
ちょっと面倒なのか再生しようとしない事例が出てきたのです。
そうだ、Cronで自動化しよう
もともと、チャイムはCronで指定時刻になるようにしていたので
音楽もCronで始業時刻に再生、終業時刻に停止するようにしました。
また、Cronでは曜日指定ができるので、土日はチャイムやBGMがなることはありません。
よし、これで解決!・・・あれ?
祝日は無人なのに音楽が鳴り続けるよ
そうです、気づきました。
Cronではあくまでも曜日指定はできるけど、日本の祝日なんて知ったことではありません。
なので、祝日は問答無用でチャイムも音楽もなってしまうのです。
なんとか、祝日はならないようにしなくちゃ・・・!
ということで、スクリプトを作りました。
作成したスクリプトの紹介
実際に作成したスクリプトが以下になります。
#!/bin/sh
target_date="01-01"
current_date=$(date +%m-%d)
temp_file="/home/user/syukujitsu_temp.csv"
target_file="/home/user/syukujitsu.csv"
# 今日がCSVダウンロード日もしくはファイルがなかったら
if [ "$current_date" = "$target_date" ] || [ ! -e "$target_file" ]; then
curl -L --compressed https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv | iconv -f SJIS -t UTF-8 > "$temp_file"
# 今年の分だけ抽出
current_year=$(date +%Y)
grep -a "^$current_year" $temp_file >> $target_file
rm -f $temp_file
# 去年の分は不要なので削除
last_year=$((current_year - 1))
sed -i "/^$last_year/d" "$target_file"
fi
# 今日の曜日を取得 (1: 月曜日, 2: 火曜日, ..., 7: 日曜日)
day_of_week=$(date +%u)
# 土曜日 (6) または日曜日 (7) だったら exit 1
if [ "$day_of_week" -eq 6 ] || [ "$day_of_week" -eq 7 ]; then
echo "今日は土曜日または日曜日です。"
exit 1
fi
date_in_csv=$(cut -d',' -f1 "$target_file")
current_date=$(date "+%Y/%-m/%-d")
if ! echo "$date_in_csv" | grep -q "$current_date"; then
echo "今日は祝日ではありません。"
exit 0
else
echo "今日は祝日です"
exit 1
fi
6行目、7行目のパスは環境に合わせて修正してください。
ある程度の処理内容はコード内のコメントを参照してください。
このスクリプトでは、内閣府が公開している国民の祝日のCSVをダウンロードして利用しています。
内閣府 – 国民の祝日について
https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html
上記のデータは、記事作成時点では昭和30年(1955年)から最新のものまでが全て含まれているため、処理実行時の年のみを抽出して書き出しています。
29行目、35行目、39行目ではexit 0やexit 1としていますが
これは、コマンドを実行する際、&&で処理をつなげるとeixt 0のときのみ
後続の処理を実行してくれるので、今回は土日や祝日じゃなければexit 0となるようにしています。
また、出力されたsyukujitsu.csvに会社の休業日などを追記すれば
祝日でなくても、処理を止められるようになります。
あとはCronと組み合わせるだけ
はい、ということで実際に登録しているCronの内容です。
0 9 * * * /bin/bash -c "sh /home/user/check_holiday.sh && /usr/bin/mpg123 '/home/user/Japanese_School_Bell03-01(Slow-Long).mp3'"
0 12 * * * /bin/bash -c "sh /home/user/check_holiday.sh && /usr/bin/mpg123 '/home/user/Japanese_School_Bell03-01(Slow-Long).mp3'"
0 13 * * * /bin/bash -c "sh /home/user/check_holiday.sh && /usr/bin/mpg123 '/home/user/Japanese_School_Bell03-01(Slow-Long).mp3'"
0 18 * * * /bin/bash -c "sh /home/user/check_holiday.sh && /usr/bin/mpg123 '/home/user/Japanese_School_Bell03-01(Slow-Long).mp3'"
これで土日や祝日以外の指定時刻にチャイムを鳴らすことができるように鳴りました。
以上!