Así es como registro tanto stdout como stderr en mis scripts (normalmente cronjobs):
#!/bin/bash
mylog() {
echo "[`date '+%Y-%m-%d %H:%M:%S'`] $1"
}
(
mylog 'start'
some-command || mylog 'error' && exit 1
mylog 'end'
) >> /var/log/my-log.log 2>&1
En algunos scripts uso return en lugar de exit y funciona bien, pero ahora dice que no puedo usar return a menos que incluya el script con src o lo use en una función. Entonces lo cambié para salir, pero el problema es que no registra nada, parece que detiene la >> redirección de salida. Otro problema es que no podré incluirlo más adelante con src, porque sólo quiero detener este script, no todo.
Utilizo la redirección de salida porque quiero registrar todo, incluso si no se produjo ningún error. Y a veces los comandos ni siquiera devuelven códigos de salida adecuados, así que no puedo confiar en eso.
Entonces, ¿cómo puedo "regresar" en caso de error? Conozco 'set -e', pero prefiero tener más control sobre cuándo detener el script.
¿Alguna idea?
Respuesta1
No puedo explicar el comportamiento que estás experimentando, pero aquí tienes una posible solución:
#!/bin/bash milog() { echo "[$(fecha '+%Y-%m-%d %H:%M:%S')] $1" } mi principal() { ( mylog 'inicio' algún comando || mylog 'error' && retorno 1 mylog 'fin' ) >> /var/log/mi-log.log 2>&1 } mi principal
Alternativamente, elimine la redirección de la mymain
definición de función y colóquela en la mymain
llamada de función:
mymain >> /var/log/my-log.log 2>&1
(Entonces también debería poder eliminar los paréntesis de la mymain
definición de la función). Alternativamente, dado que desea que IO sea redirigido para elcompletoscript, puede separar la redirección de las declaraciones de acción:
ejecutivo >> /var/log/my-log.log ejecutivo 2>&1 mi principal
Como no entiendo por qué su enfoque falla, no puedo explicar por qué es más probable que cualquiera de los anteriores funcione como se desea. Sin embargo, son formas ligeramente diferentes de hacer lo mismo y eso podría ser suficiente. Por cierto, cambié `date …`
a $(date …)
sólo por razones generales; No creo que eso tenga nada que ver con tu problema.
Respuesta2
¿Qué tal usar el screen
comando en Linux? Esto solucionaría el problema a menos que esté decidido a programar una solución usted mismo.