Tener salida de correo electrónico cron a MAILTO según el estado de salida

11

Tengo un trabajo cron que ejecuta un comando php como este:

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

Esto debería enviar solo la salida STDERR a la dirección MAILTO. Por lo que deduzco, el script php no genera ninguna información STDERR incluso cuando su estado de salida es 1.

¿Cómo puedo obtener el resultado del comando php (STDOUT) y solo enviarlo a MAILTO si el estado de salida no es cero?

Dave
fuente

Respuestas:

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

que volca la salida estándar logfiley solo la genera si falla el script (sale de un valor distinto de cero).

Nota: si su script también puede salir a, stderrentonces debe redirigir stderra stdout. De lo contrario, cualquier cosa impresa stderrhará que cron envíe un correo electrónico incluso si el código de salida es 0:

php /path/to/script.php > logfile 2>&1 || cat logfile; rm logfile
Kyle Jones
fuente
Esto también eliminará cualquier cosa que aparezca en stderr, lo que no necesariamente significa que haya un error (por ejemplo, salida de depuración).
hoffmanc
3

¿Has considerado crónico de moreutils ? Creo que hace exactamente lo que quieres:

chronic ejecuta un comando y organiza su salida estándar y su error estándar para que solo se muestren si el comando falla (sale de cero o se bloquea). Si el comando tiene éxito, cualquier salida extraña se ocultará.

En versiones recientes, hay un -einterruptor para mostrar también la salida completa si se ha escrito algo en stderr.

saraedum
fuente
2

Dado que el resultado se genera antes de que se conozca el estado de salida, deberá almacenarlo en algún lugar.

Una posibilidad es almacenarlo en una variable de shell:

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

Esto no conserva completamente la salida del script (elimina las líneas en blanco finales), pero está bien para este caso de uso. Si desea conservar las líneas en blanco al final:

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

Si potencialmente hay una gran cantidad de resultados, puede preferir almacenarlos en un archivo temporal en su lugar:

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- deja de ser malvado'
fuente