À la fois
<file.txt tee >(grep LITERAL) >(wc -l) >/dev/null
Et:
{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1
Tous tee, grepet wcsont mises en marche en même temps. Ce qui compte alors, c'est ce qui se passe à la fin.
wcn'imprimera le résultat que lorsqu'il verra la fin du fichier sur son entrée standard. Dans le premier cas, c'est à ce moment tee-là que teese termine , car alors il se fermera fdà l'autre extrémité du tuyau en cours de wclecture (démarré par substitution de processus). Il n'y a aucune garantie qui grepaura lu toutes ses entrées à ce moment-là, et encore moins écrit sa sortie (étant donné que les tuyaux peuvent contenir une quantité assez importante de données et qui wcsera probablement plus rapide que grep)
Dans le second cas, la wcfin du fichier s'affiche lorsque tous les rédacteurs du tuyau en cours de lecture ont fermé l'extrémité du tuyau. Dans ce cas cependant, il y a plusieurs écrivains. tee(via son fd ouvert sur /dev/fd/3et via son fd 3) et grepqui a également son fd3 ouvert au tuyau wc(même s'il n'en fait aucun usage, et encore moins lui écrit). L'intérieur {provoquera probablement un processus de sous-shell supplémentaire qui aura également un fd3 ouvert et attendra les deux teeet grep.
Cela signifie que wcn'écrira son numéro de ligne qu'après grepsa sortie.
Si vous l'aviez écrit de la bonne façon, c'est-à-dire en fermant les fds qui n'avaient pas besoin d'être ouverts:
{ { <file.txt tee /dev/fd/3 4>&- |
grep LITERAL >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
La commande n'aurait alors pas été garantie dans des coques qui optimisent le processus de sous-coque. Cependant, la seule coquille que je sais que cela n'est , ksh93mais ksh93utilise un socket paires pour les tuyaux, donc /dev/fd/3ne fonctionnera pas là sur Linux au moins.
Pour voir quels processus sont en cours d'exécution, vous pouvez remplacer greppar ps:
$ { { <file.txt tee /dev/fd/3 4>&- | ps -H >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
PID TTY TIME CMD
8727 pts/5 00:00:00 bash
8815 pts/5 00:00:00 bash
8817 pts/5 00:00:00 tee
8818 pts/5 00:00:00 ps
8816 pts/5 00:00:00 wc
Avec bash, vous pouvez voir ce processus de shell supplémentaire, et vous pouvez également voir que le tuyau est ouvert sur fd 3 avec:
$ (p=$BASHPID; { { <file.txt tee /dev/fd/3 4>&- | lsof -ag "$p" -d3 >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1)
COMMAND PID PGID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 9843 9842 chazelas 3w FIFO 0,8 0t0 153304 pipe
tee 9845 9842 chazelas 3w FIFO 0,8 0t0 153304 pipe
lsof 9846 9842 chazelas 3r DIR 0,3 0 1 /proc
grep LITERAL >&4 3>&- 4>&-signifie, le fd 4 semble être à la fois utilisé et fermé?