%20junto%20con%20la%20salida%20de%20error%20(stderr).png)
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 stdout
y la de error stderr
? Deben colocarse en archivos diferentes.
Respuesta1
cron
Los trabajos se ejecutan de sh
forma predeterminada e independientemente de si sh
es Bourne, POSIX sh
o 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>&1
al 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.sh
irá a la tubería a tee
.
tee
lo 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 fish
shell.
Con (t)csh
, zsh
o 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 cron
utilizar 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_IOS
caracterí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.sh
el estado de salida de 's, y también mantiene script.sh
el 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 ( ,,,, bash
al menos ) tienen una opción que puede usar para poder informar errores en cualquier componente de una canalización:ksh93
zsh
yash
mksh
pipefail
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.