bash: imposta -x registra su file


18

Ho uno script di shell con set -xun output dettagliato / debug:

#!/bin/bash

set -x
command1
command2
...

L'output è simile al seguente:

+ command1
whatever output from command1
+ command2
whatever output from command2

Il mio problema è, l'uscita shell (causata da set -x) va al stderr, mescolato con l'output dei comandi ( command1, command2, ...). Sarei felice di avere l'output "normale" sullo schermo (come lo script senza eseguire set -x) e l'output "extra" di bash separatamente in un file.

Quindi vorrei avere questo sullo schermo:

whatever output from command1
whatever output from command2

e questo in un file di registro:

+ command1
+ command2

(va bene anche se il file di registro ha tutto insieme)

Il set -x 2> fileovviamente doens't prendere il giusto effetto, perché non è l'output del comando set, ma modificare il comportamento della bash.

Anche l'utilizzo bash 2> fileper l'intero script non fa la cosa giusta, perché reindirizza lo standard di ogni comando che viene eseguito anche in questa shell, quindi non vedo il messaggio di errore dei comandi.


2
Il mio google-fu sembra essere forte questa mattina: invia l'output bash -x al file di log senza interrompere l'output standard
steeldriver

Risposte:


20

Sulla base di questa risposta ServerFault Invia l'output bash -x al file di log senza interrompere l'output standard , le versioni moderne di bash includono una BASH_XTRACEFDspecifica per specificare un descrittore di file alternativo per l'output diset -x

Quindi, per esempio, puoi farlo

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

per inviare l'output del set -xfile logfilepreservando l'output standard regolare e i flussi di errore standard per i seguenti comandi.

Nota che l'uso di fd 19 è arbitrario - deve solo essere un descrittore disponibile (cioè non 0, 1, 2 o un altro numero che hai già assegnato).


In effetti salva il registro di traccia bash separatamente, tuttavia rende davvero difficile leggere i 2 output (stdout + stderr sullo schermo e la traccia bash nei file di registro) in quanto completamente fuori sincrono. Vedi la soluzione che ho appena pubblicato .
Redseven

4

Dopo più di un anno ho trovato la soluzione giusta per avere sia l'output "normale" (stdout + stderr - traccia bash) sia tutti insieme (stdout + stderr + traccia bash) in un file (bash.log) :

exec   > >(tee -ia bash.log)
exec  2> >(tee -ia bash.log >& 2)
exec 19> bash.log

export BASH_XTRACEFD="19"
set -x

command1
command2

Questa è solo la combinazione della risposta di Steeldriver e questa .
jarno,

3

Steeldriver ti ha dato un approccio. In alternativa, puoi semplicemente reindirizzare STDERR su un file:

script.sh 2> logfile

Ciò, tuttavia, significa che sia l'output creato set -xdall'opzione sia qualsiasi altro messaggio di errore prodotto andranno al file. La soluzione di Steeldriver reindirizzerà solo l' set -xoutput che è probabilmente quello che vuoi.


"... sia l'output creato dall'opzione set -x sia qualsiasi altro messaggio di errore prodotto andranno al file." Ed è per questo che non funziona per me. Il mio problema principale è che non vedo facilmente "errori reali", perché tutto questo risultato bash va allo standard. Il reindirizzamento dei messaggi di errore dei comandi mi nasconderebbe anche gli "errori reali" in un modo diverso.
Redseven,

@redseven Temo che ciò che stai chiedendo non sia molto chiaro allora. Potresti modificare la tua domanda e chiarire? Prova a evitare l'uso del termine "output" per tutto ciò che non ha intenzione di stdout. Vuoi separare i) uscita normale; ii) eventuali errori generati dal tuo comando e iii) set -x? Allora la risposta di Steeldriver non è abbastanza? Altrimenti, mostraci un semplice script che possiamo copiare e dicci come vorresti che si comportasse.
terdon,

@steeldriver ha già risposto perfettamente alla domanda.
Redseven,

@redseven ah, cool allora. Dato che il tuo commento è arrivato molto più tardi, ho pensato che avessi ancora bisogno di qualcosa e non potevo vedere come la risposta di Steeldriver non fosse riuscita a risolvere il tuo problema. Sono contento che sia tutto ordinato allora.
terdon,
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.