¿Cómo puedo registrar completamente todas las acciones de scripts bash?


44

Quiero capturar TODOS los datos de los registros, ambos con mensajes de error, de la salida de mi script, y redirigirlos a todos al archivo de registro.

Tengo script como a continuación:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs

Quiero ver todas las acciones en el archivo /home/scripts/cron/logs

Pero solo veo esto lo que puse después del comando echo.

¿Cómo verificar los registros si el comando SSH fue exitoso?

Necesito reunir todos los datos de los registros. Necesito esto para monitorear el resultado de cada comando en mi script, para analizar mejor lo que sucede mientras el script falla.


También puede usar el "script" para realizar esto. Vea esta publicación: [aquí] [1] [1]: stackoverflow.com/questions/5985060/…
xX0v0Xx

debe tener cuidado con errexit: noté que se ignora o que el error no sale del script, por ejemplo. si tiene algo como esto en el script: comando || dosmthg cuando el comando falla, el script no sale inmediatamente con errexit establecido, solo ejecuta dosmthg y continúa el script

Respuestas:


67

Generalmente pongo algo similar al siguiente al comienzo de cada script (especialmente si se ejecutará como un demonio):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':

Explicación:

  1. exec 3>&1 4>&2

    Guarda los descriptores de archivos para que puedan restaurarse a lo que eran antes de la redirección o usarse para generar lo que eran antes de la siguiente redirección.

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    Restaurar descriptores de archivos para señales particulares. En general, no es necesario ya que deben restaurarse cuando sale el subconcha.

  3. exec 1>log.out 2>&1

    Redireccionar stdouta archivo y log.outluego redirigir stderra stdout. Tenga en cuenta que el orden es importante cuando desea que vayan al mismo archivo. stdout debe ser redirigido antes de stderrser redirigido a stdout.

A partir de entonces, para ver la salida de la consola (tal vez), puede simplemente redirigir a &3. Por ejemplo,

echo "$(date) : part 1 - start" >&3

irá a donde stdoutfue dirigido, presumiblemente la consola, antes de ejecutar la línea 3 anterior.


<< niceroot, gracias! Agregué esos threelines (exec, trap, exec) al comienzo del script y puedo obtener tanto stdout como stderr. Pero un problema: he visto "El descriptor de archivo 3 (canalización: XXX) se filtró en some_command" ... Por favor, hágame saber cómo puedo evitar obtener estos errores. Estoy usando busybox basado en sh en tablero personalizado.
kumar

3
Gran KungFu aquí! - Aún mejor es usar trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. RETURN pseudo sigspec restaura los descriptores de archivos cada vez que se ejecuta una función de shell o un script con. o la fuente integrada termina de ejecutarse. Por esto (y por otras razones) en mis scripts agrego como las últimas 2 líneas: return& exit 0- ¡Solo mis 2 centavos, felicitaciones a usted @nicerobot!
DavAlPi

Hay una buena cantidad de detalles sobre el registro de scripts de shell a través de varaibles globales de shell. Podemos emular el tipo similar de inicio de sesión en el script de shell: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html La publicación contiene detalles sobre niveles de registro de introducción como INFO, DEBUG, ERROR. Detalles de seguimiento como entrada de script, salida de script, entrada de función, salida de función.
Piyush Chordia

La enumeración de trapseñales parece un poco extraña. Por lo general, también querrás incluirlo 15.
tripleee


14

para obtener la salida ssh en su archivo de registro, debe redirigir stderra stdout. puede hacer esto agregando 2>&1después de su script bash.

Debe tener un aspecto como este:

#!/bin/bash
(
...
) 2>&1 | tee ...

cuando esto no muestre los mensajes en el orden correcto, intente agregar otra subshell:

#!/bin/bash
((
...
) 2>&1) | tee ...

1
Esto funciona muy bien. En realidad, puedes dirigir tanto stdout como stderr con:( ... ) |& tee output.log
Noam Manos

13

Mientras leo su pregunta, no desea registrar la salida, pero la secuencia completa de comandos, en cuyo caso, las otras respuestas no lo ayudarán.

Invoque scripts de shell con -x para generar todo:

sh -x foo.sh

Inicie sesión en el archivo que desee con:

sh -x foo.sh >> /home/scripts/cron/logs


2
+1 para la opción -x
Coc

10

En bash, puede poner set -xe imprimirá cada comando que ejecuta (y las variables de bash) después de eso. Puedes apagarlo con set +x.

Si quieres ser paranoico, puedes poner set -o errexittu guión. Esto significa que el script fallará y se detendrá si un comando devuelve un código de salida distinto de cero, que es la forma estándar de Unix para indicar que algo salió mal.

Si desea obtener mejores registros, debe mirar tsen el moreutilspaquete debian / ubuntu. Prefijará cada línea con una marca de tiempo y la imprimirá. Para que pueda ver cuándo estaban sucediendo cosas.


1
"set -o errexit" debe ser lo mismo que "set -e"
Ajith Antony

0

Después de lo que otros dijeron, el manual conjunto es un buen recurso. Puse:

#!/usr/bin/env bash
exec 1> command.log 2>&1
set -x

En la parte superior de los scripts, deseo continuar, o set -exsi sale por error.


¿Cómo ayudará esto para los registros ssh y la ejecución exitosa del comando?
asktyagi

Al probar con el script ficticio del OP, registra cada comando y cualquiera que sea el resultado: tiempo de espera ssh, dominio incorrecto, etc. O para una dirección ssh válida, registra los comandos en el shell remoto. Si se requiere más información sobre inicios de sesión ssh, ssh -vv¿ tal vez ?
dragon951
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.