やりたいこと
こんな感じで、シェルスクリプトをcronに定期的に実行したい。
SHELL=/bin/bash
MALITO=alert@example.com
0 0 * * * /path/to/command
そして、以下のようなポリシーでログを取りたい。
- 標準出力も標準エラー出力も、全部ログに記録する。
- 標準エラー出力があった場合は、メールを送信する。
/path/to/command >> /var/log/some
ですと標準エラー出力がログに記録されませんし、 /path/to/command >> /var/log/some 2>&1
だと標準エラー出力に出力されずメールが送信されません。
解決策
SHELL=/bin/bash
MALITO=alert@example.com
0 0 * * * (/path/to/command 2>&1 >> /var/log/some) | tee -a /var/log/some
解説
まず前半の /path/to/comand 2>&1 >> /var/log/some
です。
これは、 (...)
: サブシェルになっており、親のシェルとは別のプロセスで実行される。
そのサブシェル内では /path/to/command 2>&1 >> /var/log/some
が実行されており、 /path/to/command
の標準エラー出力の出力先を標準出力に、標準出力の出力先を /var/log/some
にする。
結果として、サブシェルからは /path/to/command
の標準エラー出力が標準出力として出てくる。
後半の | tee -a /var/log/some
は、サブシェルからでてきた標準出力を /var/log/some
に追記しつつ、そのまま標準出力に出す。
そして標準出力がある場合はcronによって、MAILTOの宛先にその内容のメールが送られる。