¿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.

Marca azul
fuente
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.

nicerobot
fuente
<< 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
1
@PiyushChordia enlace fijo: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html
vigilancer
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 ...
cristiano
fuente
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

Alex Holst
fuente
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.

Rory
fuente
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.

dragon951
fuente
¿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