¿Cómo redirigir la salida y salir en caso de error del comando?

¿Cómo redirigir la salida y salir en caso de error del comando?

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 mymaindefinición de función y colóquela en la mymainllamada de función:

mymain >> /var/log/my-log.log 2>&1

(Entonces también debería poder eliminar los paréntesis de la mymaindefinició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 screencomando en Linux? Esto solucionaría el problema a menos que esté decidido a programar una solución usted mismo.

información relacionada