cronの設定について

Linuxサーバーで定期的にバッチ処理を実行したいときは、cronにコマンドやスクリプトを設定することが多いと思います。

例えば、毎日3時30分にシェルスクリプト /path/to/batch.sh を実行するcron設定は以下のようになります。

30 3 * * * /path/to/batch.sh

 

ところが、この設定のままだと、標準出力や、何らかの不具合により標準エラー出力があった場合、(デフォルトでは)cronを設定したOSユーザー宛にメールが配送されます。
OSユーザー宛のメールはサーバー上のメールボックスに溜まり、メール転送設定を行っていれば、転送先アドレスにメールが送信されます。

よくあるケースは、「環境変数やスクリプトの実行権限の設定が適切でない」ことによる標準エラー出力でしょう。
以下は、シェルスクリプトに実行権限がついていない場合のメール本文です。

/bin/sh: /path/to/batch.sh: Permission denied

 

コマンドラインで実行したときは問題なく動作するのに、cronからの実行だとうまくいかない、ということはわりとよくあるので、cronに設定したあとは、一時的に3分後ぐらいに実行するよう設定して動作確認するとよいと思います。

また、標準出力、標準エラー出力の扱いについては、例えば、次のような方法が考えられるでしょう。

1. 標準出力も標準エラー出力も捨てる

30 3 * * * /path/to/batch.sh 1> /dev/null 2>&1

 

2. 標準出力は捨てて、標準エラー出力はメールする

30 3 * * * /path/to/batch.sh > /dev/null

 

3. 標準出力も標準エラー出力もログファイルに書き出す

30 3 * * * /path/to/batch.sh 1>> /var/log/batch.log 2>&1

 

4. 標準出力はログファイルに書き出し、標準エラー出力はメールする

30 3 * * * /path/to/batch.sh >> /var/log/batch.log

 

この中では、僕がよく採用するのは、
「4. 標準出力はログファイルに書き出し、標準エラー出力はメールする」
です。

  • 標準出力については正常な動作なのでメール通知しない。何かあったときに後から調べられるようログファイルに書き出す。
  • 標準エラー出力は、何か予期せぬ現象が発生した可能性があるので、すぐにメールで通知する。

というポリシーですね。

※ログファイルに書き出す場合は、ログローテートの設定も忘れずに。以下は、ログを月に一度ローテート、圧縮して24世代保存する場合。

 # vi /etc/logrotate.d/batch

/var/log/batch.log
{
    monthly
    rotate 24
    compress
    missingok
}

 

まとめます。
cronの設定を行うときは以下に注意します。

  • cronの設定後は、必ずcronからの実行を確認する。
  • 標準出力、標準エラー出力を考慮して設定する。
  • 不具合が発生した場合は担当者にメールで通知するよう設定する。

なぜ今さらこの記事を書いたかというと、サーバー構築業務において、
「アプリケーション開発担当者がcronに設定した1分おきとか5分おきのバッチによる標準出力や標準エラー出力によるメールが、サーバー管理者(である僕)に大量に届いて困る!」
ということがわりとよくあるからです(笑)

なお、cronの出力設定については、以下の記事が参考になります。
(MAILTOで宛先を設定できるのは知らなかった。)

・cron で > /dev/null して椅子を投げられないための3つの方法
http://sfujiwara.hatenablog.com/entry/20120613/1339547638

・Unix :: cron / 標準エラー(STDERR)のみアラートメールする
http://tm.root-n.com/unix:cron:stderr2mail

また、root宛やOSユーザー宛のメールを転送するためのPostfix関連の設定方法は、以下の記事を参照してください。

・Postfixによるメール送信設定
https://inaba-serverdesign.jp/blog/20160620/postfix_send_mail.html
 

Follow me!