やりたいこと
こんな感じで、シェルスクリプトを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の宛先にその内容のメールが送られる。