先日、本番サーバーで定期実行しているタスクのタイミングを調整したくて
crontab -e
と叩いていたら、先輩エンジニアから
「crontabには気をつけな... あいつは簡単に吹き飛ぶぞ...」
と意味深な忠告をうけた。
なぜ設定を確認しようとしただけで吹き飛ばす危険性があるのか?
不思議に思った自分はその言葉の理由を探すため、アマゾンの奥地へと向かった...
調べたら結構有名な罠らしく、もうたくさん記事も出ていたけど備忘録も兼ねて書いときます。
crontabってなんぞや
わかったつもりになってるかもしれないから、改めてcrontabについて調べておこう。
IT用語辞典によると、
crontabとは、LinuxなどのUNIX系OSで標準的に用いられる定時実行システムであるcronの設定を行うコマンドおよび設定ファイル。“cron table” の略。
利用者はcrontabファイルに実行したいコマンドやシェルスクリプトなどと実行日時を記述して保存すると、システムに常駐するデーモン(crond)がこれを読み込んで指定したスケジュールに従って実行してくれる。
とのこと。
定期実行したいタスクがある場合、大抵の場合はこれを使うことになると思う。
設定したcrontabファイルの中身は大体こんな感じ。
# 毎週日曜日の午前1時にユーザーのホームディレクトリのログファイルを削除
0 1 * * 0 rm /home/taioji/*.log > /dev/null 2>&1
# 月曜日から金曜日の午後11時30分にシェル・スクリプトbackup.shを実行
30 23 * * 1,2,3,4,5 /root/backup.sh
viエディタで「分 時 日 月 曜日 実行するコマンド」みたいに書けば勝手にやってくれるみたい。
しかもLinuxに標準搭載。お手軽!
crontabには-e
, -l
, -r
, -u
などのオプションが渡せて、それぞれ意味はこんな感じ
-u ユーザ名 ユーザを指定してcrontabを実行(rootユーザのみ使用可)
-l 現在の設定内容を表示
-e 設定を行う
-r 現在の設定を削除
crontab -e
を実行すると上記のcrontabファイルがviエディタで開かれて、確認と編集ができる。
crontabでやりたいことは大体-e
で出来るので、今まで正直crontab -e
以外は使ってない。
でもviエディタで間違えて記述を削除しちゃったらUndoすればいいし、そんな簡単にcrontabファイルが吹き飛ぶことなんてないんじゃね?
crontabが孕む危険性その1
と思って調べてるとこんな記述を発見。
注意 –
誤ってオプションを指定しないで crontab コマンドを入力した場合は、使用しているエディタの中断文字を入力してください。この文字を入力すると、変更結果を保存せずに crontab コマンドを終了できます。この場合に変更結果を保存してファイルを終了すると、既存の crontab ファイルが空のファイルで上書きされます。
なるほどオプションなしのcrontab
がファイルの新規作成にあたるのか。
確かにviエディタ慣れてない時は、急にviエディタが開いたらパニクってとりあえず':wq'みたいなこともあったかもしれない。
crontabコマンドで何をやってるかがよくわかってないと、知らないうちに空ファイルで上書きして無事死亡する可能性もあるのかも。
でもviにパニクるような人がcrontabをローカル以外で実行することなんてそんなないよな...?
と思いつつ引き続き調べていたら、ついにそのリードエンジニアが言っていたであろう、crontabの一番ヤバいところを発見した。
crontabが孕む危険性その2(本命)
先ほど挙げたcrontabのオプションの-r
。
crontabファイルを消したい時はcrontab -r
で削除できるとのこと。
試しにテスト用環境で動かそうと、キーボードで打ち込もうとした時に気付いた。
crontabで一番よく使うであろうオプションは-e
。
e
とr
って....
キー隣同士じゃねえか!!!
しかもcrontab -r
実行時は、警告とかなく一発で消してくれるらしい。 危険すぎる。
自分はだいたい5分に一回タイポしているので、これは吹き飛ばすのも時間の問題だった... あぶねえ...
対策もちゃんとあった
調べたら-r
の罠にやられた先人は数多存在するみたいで、その対策もいくつか挙げてあったからまとめる。
間違えてcrontab -r
しても警告してくれるようにする
Linuxコマンドでオプション-i
をつけると、何か削除が伴うコマンドを実行するときに確認してくれるようになる。
なのでbashのaliasを設定してcrontab実行時に勝手に-i
をつけて貰えば、間違えてcrontab -r
しても警告を挟んでくれるようになる。
localとかでbashrcをいじれる状況ならこれで良さそう。
$ vi ~/.bashrc
alias crontab='crontab -i'
$ source ~/.bashrc
そもそもcrontabを使うのをやめる
crontabは導入も楽だしわかりやすいからつい使いがちだけど、冗長化とか負荷分散とかに対応ができなかったり、rの罠が危険すぎたり色々と問題が目立つそう。
個人開発ならまだしも、ちゃんとしたサービスを動かそうとなったときにはcrontabの採用自体を考えた方が良さそう。
調べたら結構代替手段はたくさんあった。
他にもcrontab -e
を使わない運用にしたり、権限をキツくしたりといった対策があったけど、今回の自分のケースではできなさそうだったので割愛。
やらかす前にできる手はちゃんと打っておこう
万一crontabファイルを吹っ飛ばした場合は、ログを遡って頑張ってサルベージする必要があるみたい。
動いてるサービスでこれやったら終わるな.... ゾゾゾ
今はバックエンドをLaravelで書いているので、今後はLaravelのタスクスケジュールで既存のcrontabを置き換えていこうと思います。
先輩エンジニアから忠告を聞いていなかったら、100%どこかでやらかしてた自信があるので、本当に助かりました。
危うく腹を切るところでした。
参考記事
関連資料