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.
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
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é).
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.