Wyślij wyjście e-mailem cron do MAILTO na podstawie statusu wyjścia

11

Mam zadanie crona uruchamiające polecenie php w następujący sposób:

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

Powinno to wysłać tylko dane wyjściowe STDERR na adres MAILTO. Z tego, co zbieram, skrypt php nie wyświetla żadnych informacji STDERR, nawet jeśli jego status wyjścia wynosi 1.

Jak mogę uzyskać wynik polecenia php (STDOUT) i wysłać go do MAILTO tylko wtedy, gdy status wyjścia jest niezerowy?

Dave
źródło

Odpowiedzi:

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

który zrzuca standardowe wyjście logfilei wyprowadza je tylko w przypadku niepowodzenia skryptu (wyjście niezerowe).

Uwaga: jeśli twój skrypt może również wyświetlać dane wyjściowe stderr, powinieneś przekierować stderrna stdout. W przeciwnym razie wszystko, co stderrzostanie wydrukowane, spowoduje, że cron wyśle ​​wiadomość e-mail, nawet jeśli kod wyjścia to 0:

php /path/to/script.php > logfile 2>&1 || cat logfile; rm logfile
Kyle Jones
źródło
Spowoduje to również wykasowanie wszystkiego, co pojawia się w stderr, co niekoniecznie oznacza błąd (np. Wyjście debugowania).
hoffmanc
3

Czy zastanawiałeś się nad przewlekłą z moreutils . Myślę, że robi dokładnie to, co chcesz:

Chroniczny uruchamia polecenie i ustawia, aby jego standardowe wyjście i błąd standardowy były wyświetlane tylko w przypadku niepowodzenia polecenia (wyjście niezerowe lub zawieszenie się). Jeśli polecenie się powiedzie, wszelkie zewnętrzne dane wyjściowe zostaną ukryte.

W ostatnich wersjach istnieje -eprzełącznik, który pokazuje również pełny wynik, jeśli coś zostało zapisane do stderr.

saraedum
źródło
2

Ponieważ dane wyjściowe są generowane przed poznaniem statusu wyjścia, musisz je gdzieś zapisać.

Jedną z możliwości jest zapisanie go w zmiennej powłoki:

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

Nie zachowuje to całkowicie wyniku skryptu (usuwa końcowe puste linie), ale w tym przypadku jest to w porządku. Jeśli chcesz zachować końcowe puste linie:

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

Jeśli istnieje potencjalnie dużo danych wyjściowych, możesz zamiast tego zapisać je w pliku tymczasowym:

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
Gilles „SO- przestań być zły”
źródło