Il est beaucoup plus facile de visualiser les choses si vous pensez à ce qui se passe réellement avec les "redirections" et les "pipes". Les redirections et les pipes en bash ne font qu'une chose : modifier l'endroit où les descripteurs de fichiers de processus 0, 1 et 2 pointent (voir /proc/[pid]/fd/*).
Lorsqu'un tuyau ou "|" est présent sur la ligne de commande, la première chose qui se produit est que bash crée un fifo et fait pointer le FD 1 de la commande de gauche vers ce fifo, et fait pointer le FD 0 de la commande de droite vers le même fifo.
Ensuite, les opérateurs de redirection pour chaque côté sont évalués de gauche à droite et les paramètres actuels sont utilisés chaque fois que le descripteur est dupliqué. Ceci est important car, puisque le tube a été configuré en premier, les FD1 (côté gauche) et FD0 (côté droit) sont déjà modifiés par rapport à ce qu'ils auraient pu être normalement, et toute duplication de ceux-ci reflétera ce fait.
Par conséquent, lorsque vous tapez quelque chose comme ce qui suit :
command 2>&1 >/dev/null | grep 'something'
Voici ce qui se passe, dans l'ordre :
- un tuyau (fifo) est créé. "command FD1" est pointé sur ce tuyau. "grep FD0" est également pointé vers ce tube.
- "La commande FD2 est dirigée vers l'endroit où pointe actuellement la commande FD1 (le tuyau).
- "commande FD1" pointe vers /dev/null
Ainsi, toute la sortie que "command" écrit dans son FD 2 (stderr) se retrouve dans le tuyau et est lue par "grep" de l'autre côté. Toute la sortie que "command" écrit dans son FD 1 (stdout) se retrouve dans /dev/null.
Si, à la place, vous exécutez ce qui suit :
command >/dev/null 2>&1 | grep 'something'
Voici ce qui se passe :
- un tuyau est créé et "command FD 1" et "grep FD 0" y sont pointés
- "command FD 1" est pointé vers /dev/null
- "commande FD 2" est pointée là où FD 1 pointe actuellement (/dev/null)
Donc, tous les stdout et stderr de "command" vont dans /dev/null. Rien ne va dans le tuyau, et donc "grep" se fermera sans rien afficher à l'écran.
Notez également que les redirections (descripteurs de fichiers) peuvent être en lecture seule (<), en écriture seule (>) ou en lecture-écriture (<>).
Une dernière note. Le fait qu'un programme écrive quelque chose dans FD1 ou FD2 dépend entièrement du programmeur. Une bonne pratique de programmation dicte que les messages d'erreur doivent aller dans le FD 2 et la sortie normale dans le FD 1, mais vous trouverez souvent une programmation bâclée qui mélange les deux ou ignore la convention.
2 votes
Une question similaire, mais en retenant la sortie : unix.stackexchange.com/questions/3514/
0 votes
Cette question s'adressait à Bash, mais il est utile de mentionner ce lien. article pour la coquille Bourne / Almquist.
18 votes
Je m'attendais à quelque chose comme ça :
command 2| othercommand
. Bash est si parfait que son développement s'est arrêté en 1982, donc nous ne verrons jamais cela dans bash, j'en ai peur.5 votes
@Rolf Que voulez-vous dire ? Bash est mis à jour assez régulièrement ; la syntaxe que vous proposez n'est pas très bonne, car elle entre en conflit avec les conventions existantes, mais vous pouvez en fait utiliser
|&
pour canaliser à la fois stderr et stdout (ce qui n'est pas exactement ce que l'OP demande, mais assez proche de ce que je suppose que votre proposition pourrait signifier).0 votes
@tripleee Je veux dire que le développement des fonctionnalités ou de la syntaxe semble avoir pris fin ou se produire à un rythme très lent ; par conséquent, nous semblons être coincés avec une syntaxe qui a été déterminée il y a des décennies.