web-dev-qa-db-fra.com

bash: définit les journaux -x dans un fichier

J'ai un script Shell avec set -x pour avoir une sortie commentée/déboguée:

#!/bin/bash

set -x
command1
command2
...

La sortie ressemble à ceci:

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

Mon problème est que la sortie du shell (causée par set -x) est dirigée vers le stderr, mélangée à la sortie des commandes (command1, command2, ...). Je serais heureux d’avoir la sortie "normale" à l’écran (comme le script exécuté sans set -x) et la sortie "supplémentaire" de bash séparément dans un fichier.

J'aimerais donc avoir ceci à l'écran:

whatever output from command1
whatever output from command2

et ceci dans un fichier journal:

+ command1
+ command2

(aussi bien si le fichier journal a tout ensemble)

Le set -x 2> file ne prend évidemment pas le bon effet, car ce n'est pas la sortie de la commande set, mais cela modifie le comportement de la bash.

Utiliser bash 2> file pour le script entier ne fait pas non plus l'affaire, car il redirige également le stderr de toutes les commandes exécutées dans ce shell. Je ne vois donc pas le message d'erreur des commandes.

17
redseven

Après plus d'un an, j'ai trouvé la bonne solution pour avoir à la fois la sortie "normale" (stdout + stderr - trace bash) à l'écran et le tout (stdout + stderr + trace bash) dans un fichier (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
3
redseven

Sur la base de cette réponse ServerFault Envoi de la sortie bash -x au fichier journal sans interrompre la sortie standard , les versions modernes de bash incluent un BASH_XTRACEFD spécifiquement conçu pour spécifier un autre descripteur de fichier pour la sortie de set -x

Donc, par exemple, vous pouvez faire

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

envoyer la sortie de set -x au fichier logfile tout en préservant la sortie standard standard et les flux d’erreurs standard des commandes suivantes.

Notez que l'utilisation de fd 19 est arbitraire - il doit simplement s'agir d'un descripteur disponible (c'est-à-dire pas 0, 1, 2 ou un autre numéro que vous avez déjà attribué).

18
steeldriver

Steeldriver vous a donné une approche. Alternativement, vous pouvez simplement rediriger STDERR vers un fichier:

script.sh 2> logfile

Cela signifie toutefois que la sortie créée par l'option set -x et tout autre message d'erreur généré ira au fichier. La solution de Steeldriver ne fera que rediriger la sortie set -x qui correspond probablement à ce que vous souhaitez.

3
terdon