web-dev-qa-db-fra.com

Avec bash, comment puis-je canaliser l'erreur standard dans un autre processus?

Il est bien connu de canaliser la sortie standard d'un processus vers une autre entrée de processus:

proc1 | proc2

Mais que faire si je veux envoyer l'erreur standard de proc1 à proc2 et laisser la sortie standard à son emplacement actuel? Vous penseriez que bash aurait une commande du type:

proc1 2| proc2

Mais hélas non. Y a-t-il un moyen de faire ça?

108
paxdiablo

Il y a aussi substitution de processus . Ce qui fait qu'un processus se substitue à un fichier.
Vous pouvez envoyer stderr dans un fichier comme suit:

process1 2> file

Mais vous pouvez substituer un processus au fichier comme suit:

process1 2> >(process2)

Voici un exemple concret qui envoie stderr à la fois à l’écran et s’ajoute à un fichier journal.

sh myscript 2> >(tee -a errlog)
137
Scot

Vous pouvez utiliser l’astuce suivante pour swap stdout et stderr. Ensuite, vous utilisez simplement la fonctionnalité de canal normal.

( proc1 3>&1 1>&2- 2>&3- ) | proc2

Si stdout et stderr sont tous deux pointés au même endroit au début, cela vous donnera ce dont vous avez besoin.

Le bit x>y consiste à changer le descripteur de fichier x de sorte qu'il envoie maintenant ses informations à l'emplacement où le descripteur de fichier y pointe actuellement. Pour notre cas spécifique:

  • 3>&1 crée un new handle 3 qui sera affiché dans le current handle 1 (stdout d'origine), afin de le sauvegarder quelque part pour le dernier point ci-dessous.
  • 1>&2 modifie le handle 1 (stdout) afin de l'afficher dans le fichier current handle 2 (stderr d'origine).
  • 2>&3- modifie le handle 2 (stderr) afin de le sortir vers current handle 3 (stdout d'origine), puis ferme le handle 3 (via le - à la fin).

C'est effectivement la commande d'échange que vous voyez dans les algorithmes de tri:

temp   = value1;
value1 = value2;
value2 = temp;
85
paxdiablo

Bash 4 a cette fonctionnalité:

Si '| &' est utilisé, l'erreur standard de commande1 est connectée à l'entrée standard de commande2 via le canal; c'est un raccourci pour 2> & 1 |. Cette redirection implicite de l'erreur standard est effectuée après les redirections spécifiées par la commande.

zsh a également cette fonctionnalité.

-

Pour les autres/anciens coquillages, entrez simplement ceci explicitement

FirstCommand 2> & 1 | OtherCommand

63

L'échange est excellent car il résout le problème. Au cas où vous n’auriez même pas besoin de la stdout d’origine, vous pouvez le faire de cette façon:

proc1 2>&1 1>/dev/null | proc2

L'ordre est vital. vous ne voudriez pas:

proc1 >/dev/null 2>&1 | proc1

Comme cela va tout rediriger vers /dev/null!

25
kccqzy

Aucun de ceux-ci n'a vraiment très bien fonctionné. Le meilleur moyen que j'ai trouvé de faire ce que vous vouliez est:

(command < input > output) 2>&1 | less

Cela ne fonctionne que dans les cas où command n'a pas besoin d'une entrée au clavier. par exemple:

(gzip -d < file.gz > file) 2>&1 | less

mettrait les erreurs gzip en moins

0
sbingner