Sowohl
<file.txt tee >(grep LITERAL) >(wc -l) >/dev/null
Und:
{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1
Alle tee, grepund wcwerden gleichzeitig gestartet. Was dann zählt, ist was am Ende passiert.
wcdruckt das Ergebnis nur, wenn das Dateiende auf seiner Standardeingabe angezeigt wird. Im ersten Fall, das ist , wenn teeAusfahrten, weil dann teeseine schließen wird fdam anderen Ende des Rohres , das wcaus (Gestartet von Prozess - Substitution) liest. Dafür gibt es keine Garantiegrep bis zu diesem Zeitpunkt alle Eingaben gelesen wurden, geschweige denn die Ausgaben geschrieben wurden (da Pipes eine ziemlich große Datenmenge aufnehmen können und dies wcwahrscheinlich schneller sein wird als grep).
Im zweiten Fall wcwird das Dateiende angezeigt, wenn alle Schreiber der Pipe, von der gelesen wird, ihr Pipe-Ende geschlossen haben. In diesem Fall gibt es jedoch mehrere Autoren. tee(über sein fd open on /dev/fd/3und über sein fd 3) und grepdas auch seine fd3 offen für das Rohr hat wc(obwohl es es nicht benutzt, geschweige denn darauf schreibt). Das Innere {wird wahrscheinlich einen zusätzlichen Subshell-Prozess verursachen, bei dem auch eine fd3 geöffnet ist und auf beide teeund gewartet wird grep.
Das bedeutet, dass wcdie Zeilennummer erst nach dem grepBeenden geschrieben wird.
Hatten Sie es richtig geschrieben, indem Sie die FDS geschlossen haben, die nicht geöffnet werden mussten:
{ { <file.txt tee /dev/fd/3 4>&- |
grep LITERAL >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
Dann wäre die Reihenfolge in Shells, die den Subshell-Prozess optimieren, nicht garantiert worden. Die einzige Shell, die ich kenne, ist ksh93aberksh93 Verwendungen Buchsenpaare für Rohre, so /dev/fd/3wird nicht da zumindest unter Linux arbeiten.
Um zu sehen , welche Prozesse ausgeführt werden , können Sie ersetzen grepmit 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
Mit bashkönnen Sie diesen zusätzlichen Shell-Prozess sehen, und Sie können sehen, dass auch die Pipe auf fd 3 geöffnet ist mit:
$ (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>&-dass der fd 4 sowohl verwendet als auch geschlossen zu sein scheint?