Supposons que je lance une commande ou un script shell et qu'il me donne une sortie. Sans connaître les éléments internes de cette commande ou de ce script shell, comment déterminer si la sortie provient de stderr
ou stdout
?
Pour, par exemple,
$ ls -ld /
drwxrwxr-t 35 root admin 1258 Dec 11 19:16 /
contre
ls -ld /test
ls: /test: No such file or directory
Comment puis-je m'assurer que la première commande est imprimée stdout
et la seconde stderr
(l'a-t-elle fait?)?
stderred
dans votre environnement shellLD_PRELOAD
pour obtenirstdout
etstderr
dans différentes couleurs. Voici une question connexe dans la même veine.Réponses:
Il n'y a aucun moyen de savoir une fois que la sortie a déjà été imprimée. Dans ce cas, les deux
stdout
etstderr
sont connectés au terminal, les informations sur le flux qui a été écrit ont déjà été perdues au moment où le texte est apparu sur votre terminal; ils ont été combinés par le programme avant même d'arriver au terminal.Ce que vous pouvez faire, dans un cas comme celui ci-dessus, serait d’exécuter la commande avec
stdout
etstderr
redirigé vers différents endroits et de voir ce qui se passe. Ou exécutez-le deux fois, une fois avecstdout
redirigé vers/dev/null
et une fois avecstderr
redirigé vers/dev/null
, et voyez lequel de ces cas entraîne l'affichage du texte.Vous pouvez rediriger
stdout
vers/dev/null
en cliquant>/dev/null
sur à la fin de la ligne de commande et vous pouvez également redirigerstderr
vers/dev/null
en ajoutant2>/dev/null
.la source
Vous pouvez rediriger stdout en utilisant
> file
et rediriger en utilisant stderr2> file
. De nombreux shells modernes supportent la redirection vers les commandes, vous pouvez donc utilisersed
pour mettre en évidence quelle sortie provient de quel flux:la source
(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
Le
annotate-output
script de Debiandevscripts
vous permet de le faire de manière sélective:La deuxième colonne indique stdout et stderr avec
O
etE
respectivement.Il y a quelques mises en garde, la principale étant comme indiqué dans les autres réponses: vous ne pouvez pas le faire après coup. Ni le shell ni le terminal ne savent comment un programme arbitraire utilise ses descripteurs de fichier, bien que le shell soit responsable de leur configuration initiale.
Cette méthode utilise fifos, l'écriture sur un fifo peut se comporter différemment de l'écriture sur un tty, et écrire sur deux fifos différents est nettement différent (problèmes de synchronisation / d'entrelacement potentiels). En outre, il ne convient pas à une utilisation interactive, par exemple, ce
annotate-output bash
n'est pas un bon plan, mais il est utile à de nombreuses autres fins. Il existe de très nombreux exemples de scripts et de fonctions shell répondant aux questions connexes sur la colorisation de stdin / stdout / stderr. Le plus robuste est stderrd, qui utilise la modification à l'exécution (la plupart) des programmes pour modifier les données écrites sur stderr.Cette question à laquelle Anko se réfère a de bonnes réponses sur ce thème: coloriser la sortie stdout / stderr: Puis-je configurer mon shell pour imprimer STDERR et STDOUT dans des couleurs différentes?
la source
bash
script utilisant deswhile read
boucles et exécutant unedate
commande pour chaque ligne de stdout ou stderr, de sorte qu'il sera beaucoup moins efficace que soncmd > >(ts '%T O:') 2> >(ts '%T E:')
équivalent.Outre les autres réponses, il est intéressant de souligner
/proc/$PID/fd
(bien que cela ne réponde pas à la question):Comme vous le voyez, vous pouvez voir ici les descripteurs de fichier ouverts pour un processus.
0
est leSTDIN
,1
est leSTDOUT
et2
est leSTDERR
. Si vous ne redirigiez pas STDOUT ou STDERR, vous verriez/dev/pts/33
(dans cet exemple au moins) car ils pointeraient vers le terminal.notes :
/proc/$PID
existe uniquement pour les processus en cours d'exécution. Dans ce cas, j’ai utilisécat
sans arguments afin que cela ne se termine pas avant la fermeture du fichierSTDIN
. Je l'ai également exécuté en arrière-plan, de sorte que j'ai le PID immédiatement pour cet exemple.la source
Ce que vous demandez n'est pas tout à fait clair, mais cela pourrait aider
La source
Si le code de sortie est 0 cela signifie simplement que la commande est exécutée correctement (stdout), ici vous pouvez trouver des significations si le code de sortie est différent de 0 (stderr)
la source
stdout
et non-zéro impliquestderr
?stderr
et de retourner un bon code d'erreur, ou d'écrirestdout
et de retourner un mauvais code d'erreur. En fait, essayezfind /root
- en supposant que vous n’exécutez pas en tant que root, vous devriez obtenir 2 lignes imprimées - "/ root" est imprimé surstdout
, et "find: / root: Autorisation refusée" est imprimé surstderr
. Et find renvoie un mauvais code de retour.STDERR aura généralement le nom du programme ajouté au message avec deux points.
Exemple:
Contre
la source
Pour capturer et tester la sortie d'erreur:
la source