Capture la salida normal (stdout) junto con la salida de error (stderr)

Capture la salida normal (stdout) junto con la salida de error (stderr)

Hay un script que se ejecuta mediante cron con la siguiente línea:

0 * * * * (/var/script.sh | tee -a /var/script.log)

¿Cómo reescribo la entrada cron para capturar la salida normal stdouty la de error stderr? Deben colocarse en archivos diferentes.

Respuesta1

cronLos trabajos se ejecutan de shforma predeterminada e independientemente de si shes Bourne, POSIX sho compatible, la sintaxis sería:

0 * * * * /var/script.sh 2>&1 | tee -a /var/script.log

Donde |hace que los dos comandos en cada lado se ejecuten en paralelo conectados con una tubería con la salida estándar (fd 1) del izquierdo conectada al extremo de escritura de la tubería y la entrada estándar (fd 0) del derecho conectada a el final de la lectura.

Al agregar 2>&1al de la izquierda, tenemos el fd 2 (stderr) que apunta al mismo recurso señalado por fd 1: el extremo de escritura de la tubería, por lo que tanto la salida normal como la de error de script.shirá a la tubería a tee.

teelo escribirá tanto en su salida estándar (que en el caso de un trabajo cron es un archivo temporal o de canalización que se usará para enviar un correo electrónico al usuario) como en script.log.

Esa sintaxis también funciona en el fishshell.

Con (t)csh, zsho bash(4.0 o posterior), también puedes hacer:

SHELL=/bin/zsh # or tcsh, bash ...
0 * * * * /var/script.sh |& tee -a /var/script.log

( SHELL=/bin/zsh¿Dónde se indica cómo cronutilizar un shell diferente para interpretar las líneas de comando)?

En fish, usarías &|en lugar de |&.

Con rc(el que será sucesor de sh) o derivados, la sintaxis es:

SHELL=/bin/rc # or es, akanga
0 * * * * /var/script.sh >[2=1] | tee -a /var/script.log

Con zsh, también podrás prescindir tee gracias a su MULT_IOScaracterística:

SHELL=/bin/zsh
0 * * * * /var/script.sh >&1 2>&2 >>& /var/script.log

Lo que también tendría el beneficio de preservar script.shel estado de salida de 's, y también mantiene script.shel stderr de 's yendo al stderr original además de script.log(aunque eso no hace mucha diferencia en un trabajo cron donde stdout y stderr generalmente van al stderr mismo lugar de todos modos).

Algunos shells tipo Bourne/POSIX ( ,,,, bashal menos ) tienen una opción que puede usar para poder informar errores en cualquier componente de una canalización:ksh93zshyashmkshpipefail

SHELL=/bin/ksh # or zsh, bash...
0 * * * * set -o pipefail && /var/script.sh 2>&1 | tee -a /var/script.log

Respuesta2

cron quiere informarle sobre cualquier trabajo cron que produzca resultados. Quiere enviarle los resultados por correo electrónico. Si no desea recibir correos electrónicos de cron, asegúrese de que sus trabajos no produzcan resultados: no los use tee, simplemente redirija el resultado

0 * * * * /var/script.sh >> /var/script.log 2>&1

Tenga en cuenta que también eliminé los paréntesis: no tiene sentido ejecutar el script en un subshell.

información relacionada