Di keduanya
<file.txt tee >(grep LITERAL) >(wc -l) >/dev/null
Dan:
{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1
Semua tee
, grep
dan wc
dimulai secara bersamaan. Yang penting adalah apa yang terjadi pada akhirnya.
wc
hanya akan mencetak hasilnya ketika melihat akhir file pada input standarnya. Dalam kasus pertama, saat itulah tee
keluar, karena kemudian tee
akan menutup fd
di ujung pipa yang wc
membaca (dimulai dengan proses substitusi). Tidak ada jaminan bahwa grep
akan membaca semua inputnya pada saat itu, apalagi menuliskan hasilnya (mengingat pipa dapat menampung cukup banyak data dan itu wc
kemungkinan akan lebih cepat daripada grep
)
Dalam kasus kedua, wc
akan melihat akhir file ketika semua penulis ke pipa yang dibacanya telah menutup ujung pipa mereka. Namun dalam hal itu, ada beberapa penulis. tee
(melalui fd terbuka /dev/fd/3
dan melalui fd 3) dan grep
yang juga memiliki fd
3 terbuka untuk pipa wc
(meskipun tidak memanfaatkannya, apalagi menulis untuk itu). Bagian dalam {
kemungkinan akan menyebabkan proses subkulit tambahan yang juga akan memiliki fd
3 terbuka dan akan menunggu keduanya tee
dan grep
.
Itu berarti bahwa wc
hanya akan menulis nomor baris setelah grep
keluar.
Apakah Anda menulisnya dengan cara yang benar, yaitu dengan menutup fds yang tidak perlu dibuka:
{ { <file.txt tee /dev/fd/3 4>&- |
grep LITERAL >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
Maka pesanan tidak akan dijamin dalam cangkang yang mengoptimalkan proses subkulit. Namun, satu-satunya shell yang saya tahu yang melakukannya adalah ksh93
tetapi ksh93
menggunakan pasangan soket untuk pipa, jadi /dev/fd/3
tidak akan bekerja di Linux setidaknya.
Untuk melihat proses apa yang sedang berjalan, Anda dapat menggantinya grep
dengan 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
Dengan bash
, Anda dapat melihat proses shell ekstra, dan Anda dapat melihatnya juga memiliki pipa dibuka pada fd 3 dengan:
$ (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>&-
artinya, fd 4 tampaknya digunakan dan ditutup?