web-dev-qa-db-ja.com

終了ステータスに基づいてcron電子メールをMAILTOに出力します

次のようなphpコマンドを実行するcronジョブがあります。

php /path/to/script.php > dev/null

これにより、MAILTOアドレスにSTDERR出力のみが送信されます。私が収集したものから、終了ステータスが1の場合でも、phpスクリプトはSTDERR情報を出力していません。

Phpコマンド(STDOUT)の出力を取得して、終了ステータスがゼロ以外の場合にのみMAILTOに送信するにはどうすればよいですか?

11
Dave
php /path/to/script.php > logfile || cat logfile; rm logfile

これは、標準出力をlogfileにダンプし、スクリプトが失敗した(ゼロ以外の値を返す)場合にのみ出力します。

注:スクリプトがstderrにも出力する場合は、stderrstdoutにリダイレクトする必要があります。それ以外の場合、stderrに出力されるものはすべて、終了コードが0であってもcronからメールを送信します。

php /path/to/script.php > logfile 2>&1 || cat logfile; rm logfile
12
Kyle Jones

moreutils から chronic を検討しましたか?私はそれがあなたが望むことを正確にすると思います:

chronicはコマンドを実行し、コマンドが失敗した(ゼロ以外の値を出力するかクラッシュする)場合にのみ標準出力と標準エラーが表示されるように調整します。コマンドが成功した場合、無関係な出力は非表示になります。

最近のバージョンでは、-eスイッチを指定すると、stderrに何かが書き込まれた場合に完全な出力も表示されます。

3
saraedum

出力は終了ステータスがわかる前に生成されるため、どこかに保存する必要があります。

1つの可能性は、それをシェル変数に格納することです。

output=$(php /path/to/script.php)
if [ $? -ne 0 ]; then
  printf "%s\n" "$output"
fi

これはスクリプトの出力を完全に保存するわけではありません(後続の空白行を削除します)が、この使用例では問題ありません。末尾の空白行を保持したい場合:

output=$(php /path/to/script.php; ret=$?; echo a; exit $ret)
if [ $? -ne 0 ]; then
  printf "%s" "${output%a}"
fi

潜在的に大量の出力がある場合は、代わりに一時ファイルに保存することをお勧めします。

output_file=$(mktemp /var/tmp/script.XXXXXXXXXX.out)
php /path/to/script.php >>"$output_file"
ret=$?
if [ $ret -ne 0 ]; then
  echo "script.php failed (status $ret), see the output in $output_file"
fi