J'ai un fichier bash dont j'ai besoin pour rediriger toutes les sorties vers un seul fichier, le journal de débogage ainsi que vers le terminal. Je dois rediriger stdout et stderr vers le débogage et le consigner pour toutes les commandes du script.
Je ne veux pas ajouter 2>&1 | tee -a $DEBUG
pour chaque commande dans le fichier. Je pourrais vivre avec | tee -a $DEBUG
.
Je me souviens qu'il y avait un moyen de le faire avec quelque chose comme exec 2>&1
.
Actuellement, j'utilise quelque chose comme ce qui suit:
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
mais ça ne marche pas. Est-ce que quelqu'un a une solution / peut expliquer la cause?
|&
fonctionne comme un raccourci2>&1 |
, c’est au moins un peu plus pratique.Réponses:
En ce qui concerne une solution pour rediriger beaucoup de commandes à la fois:
Pourquoi votre solution d'origine ne fonctionne-t-elle pas: exec 2> & 1 redirige la sortie d'erreur standard vers la sortie standard de votre shell, qui, si vous exécutez votre script à partir de la console, sera votre console. la redirection de canal sur les commandes ne fera que rediriger la sortie standart de la commande.
Du point de vue de
somecommand
, sa sortie standard va dans un tuyau connecté àtee
et l'erreur standard va dans le même fichier / pseudofile que l'erreur standard du shell, que vous redirigez vers la sortie standard du shell, qui sera le console si vous exécutez votre programme à partir de la console.La seule vraie façon de l'expliquer est de voir ce qui se passe réellement:
L'environnement d'origine de votre shell peut ressembler à ceci si vous l'exécutez à partir du terminal:
Après avoir redirigé l'erreur standard vers la sortie standard (
exec 2>&1
), vous ne changez rien en gros. Mais si vous redirigez la sortie standard du script vers un fichier, vous obtiendrez un environnement comme celui-ci:Ensuite, rediriger l'erreur standard du shell dans la sortie standard se terminerait ainsi:
L'exécution d'une commande héritera de cet environnement. Si vous exécutez une commande et que vous la dirigez vers tee, l'environnement de la commande serait le suivant:
Donc l'erreur standard de votre commande va toujours dans ce que le shell utilise comme erreur standard.
Vous pouvez réellement voir l’environnement d’une commande en regardant dans
/proc/[pid]/fd
: utiliserls -l
pour lister également le contenu du lien symbolique. Le0
fichier ici est une entrée standard,1
une sortie standard et2
une erreur standard. Si la commande ouvre plus de fichiers (et la plupart des programmes le font), vous les verrez également. Un programme peut également choisir de rediriger ou de fermer ses entrées / sorties standard et de les réutiliser0
,1
et2
.la source
Vous pouvez utiliser exec comme ceci en haut de votre script:
Par exemple:
Me donne la sortie au fichier
$HOME/somefile.log
et au terminal comme ceci:la source
/bin/sh
scripts (de nombreuses personnes utilisent à tort la syntaxe bash dans les/bin/sh
scripts)./dev/fd/62: Operation not supported
des indices?myscript
et que je cours./myscript > /dev/null
, je devrais quand même voir d'bye
où vientecho bye >&2
.Écrivez stderr et stdout dans un fichier, affichez stderr à l'écran (sur stdout)
Utile pour crons, afin que vous puissiez recevoir des erreurs (et seulement des erreurs) par courrier
la source