Come posso registrare completamente tutte le azioni degli script bash?


44

Voglio acquisire TUTTI i dati dei registri, entrambi con messaggi di errore, dal mio output di script e reindirizzarli tutti al file di registro.

Ho una sceneggiatura come di seguito:

#!/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

Voglio vedere tutte le azioni nel file /home/scripts/cron/logs

Ma vedo solo ciò che ho inserito dopo il comando echo.

Come eseguire il check in dei log Il comando SSH è stato eseguito correttamente?

Devo raccogliere tutti i dati dei registri. Ne ho bisogno per monitorare il risultato di ogni comando nel mio script, per analizzare meglio cosa succede mentre lo script fallisce.


È inoltre possibile utilizzare lo "script" per eseguire ciò. Vedi questo post: [qui] [1] [1]: stackoverflow.com/questions/5985060/...
xX0v0Xx

devi stare attento con errexit - ho notato che viene ignorato o l'errore non esce dallo script, ad es. se hai qualcosa del genere nello script: comando || dosmthg quando il comando fallisce lo script non si chiude immediatamente con errexit impostato ma esegue dosmthg e continua lo script

Risposte:


67

Di solito metto qualcosa di simile al seguente all'inizio di ogni script (specialmente se verrà eseguito come demone):

#!/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':

Spiegazione:

  1. exec 3>&1 4>&2

    Salva i descrittori di file in modo che possano essere ripristinati su qualunque cosa fossero prima del reindirizzamento o utilizzati per eseguire l'output su qualunque cosa fossero prima del reindirizzamento seguente.

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

    Ripristina i descrittori di file per segnali particolari. In genere non sono necessari poiché dovrebbero essere ripristinati quando esce la sotto-shell.

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

    Reindirizza stdoutal file log.outquindi reindirizza stderra stdout. Nota che l'ordine è importante quando vuoi che vadano sullo stesso file. stdout deve essere reindirizzato prima di stderressere reindirizzato a stdout.

Da quel momento in poi, per vedere l'output sulla console (forse), puoi semplicemente reindirizzare a &3. Per esempio,

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

andrà ovunque stdoutfosse diretto, presumibilmente la console, prima di eseguire la riga 3 sopra.


<< niceroot, grazie! Ho aggiunto quelle tre righe (exec, trap, exec) all'inizio dello script e sono in grado di ottenere sia stdout che stderr. Ma un problema: ho visto "Il descrittore di file 3 (pipe: XXX) trapelato su some_command" ... Per favore fatemi sapere come posso evitare di ottenere questi errori. Uso sh basato su busybox nella scheda personalizzata.
Kumar,

3
Ottimo KungFu qui !!! - Ancora meglio è usare trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN. Lo pseudo sigspec RETURN ripristina i descrittori di file ogni volta che una funzione di shell o uno script eseguito con. oppure i builtin di origine terminano l'esecuzione. Per questo (e per altri motivi) nei miei script aggiungo come ultime 2 righe: return& exit 0- Solo i miei 2 centesimi, complimenti a te @nicerobot!
DavAlPi

C'è una buona quantità di dettagli sulla registrazione per gli script di shell tramite le variabili globali di shell. Possiamo emulare lo stesso tipo di registrazione nello script della shell: cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html Il post contiene dettagli sull'introduzione di livelli di registro come INFO, DEBUG, ERROR. Tracciare dettagli come voce di script, uscita di script, voce di funzione, uscita di funzione.
Piyush Chordia

L'enumerazione dei trapsegnali sembra leggermente strana. Di solito ti consigliamo di includere 15anche.
Tripleee


14

per ottenere l'output di ssh nel tuo file di log, devi reindirizzare stderra stdout. puoi farlo aggiungendo 2>&1dopo il tuo script bash.

Dovrebbe sembrare come questo:

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

quando questo non mostra i messaggi nell'ordine giusto, prova ad aggiungere un altro sotto-shell:

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

1
Funziona benissimo. In realtà puoi dirigere sia stdout che stderr con:( ... ) |& tee output.log
Noam Manos

13

Mentre leggo la tua domanda, non vuoi registrare l'output, ma l'intera sequenza di comandi, nel qual caso le altre risposte non ti aiuteranno.

Invoca gli script di shell con -x per generare tutto:

sh -x foo.sh

Accedi al file desiderato con:

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


2
+1 per l'opzione -x
Coc

10

In bash, puoi mettere set -xe stamperà ogni comando che esegue (e le variabili bash) dopo quello. Puoi spegnerlo con set +x.

Se vuoi essere paranoico, puoi inserire la set -o errexittua sceneggiatura. Questo significa che lo script fallirà e si fermerà se un comando restituisce un codice di uscita diverso da zero, che è il modo standard unix per segnalare che qualcosa è andato storto.

Se vuoi ottenere registri più belli, dovresti guardare tsnel moreutilspacchetto debian / ubuntu. Farà precedere ogni riga con un timestamp e lo stamperà. Quindi puoi vedere quando stavano accadendo le cose.


1
"set -o errexit" deve essere la stessa cosa di "set -e"
Ajith Antony,

0

A seguito di ciò che altri hanno detto, il manuale impostato è una buona risorsa. Metto:

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

Nella parte superiore degli script vorrei continuare, o set -exse dovesse uscire in caso di errore.


In che modo ciò aiuterà i registri ssh e l'esecuzione corretta del comando?
asktyagi,

Test con lo script fittizio dell'OP, registra ogni comando e qualunque sia il risultato: timeout ssh, dominio errato, ecc. O per un indirizzo ssh valido, registra i comandi nella shell remota. Se sono necessarie ulteriori informazioni sugli accessi ssh, forse ssh -vv?
dragon951
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.