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?
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)
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;
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
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
!
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