दोनों मे
<file.txt tee >(grep LITERAL) >(wc -l) >/dev/null
तथा:
{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1
सभी tee
, grep
और wc
समवर्ती रूप से शुरू किए जाते हैं। तब जो मायने रखता है वह अंत में होता है।
wc
केवल तभी परिणाम प्रिंट करेगा जब वह अपने मानक इनपुट पर एंड-ऑफ-फ़ाइल देखता है। पहले मामले में, जब वह tee
बाहर निकलता है, क्योंकि तब पाइप के दूसरे छोर पर tee
उसे बंद कर देगा fd
जो कि wc
(प्रक्रिया प्रतिस्थापन द्वारा शुरू) से पढ़ रहा है। इस बात की कोई गारंटी नहीं grep
है कि उस समय तक इसके सभी इनपुट को पढ़ा होगा, अकेले ही इसका आउटपुट लिखा होगा (यह देखते हुए कि पाइप काफी बड़ी मात्रा में डेटा पकड़ सकते हैं और wc
संभवत: इससे अधिक तेजी से होगा grep
)
दूसरे मामले में, wc
एंड-ऑफ़-द-फ़ाइल देखेंगे , जब पाइप को पढ़ने वाले सभी लेखकों ने पाइप के अपने अंत को बंद कर दिया है। उस मामले में, हालांकि, कई लेखक हैं। tee
(इसके fd के /dev/fd/3
माध्यम से और इसके fd 3 के माध्यम से खुला ) और grep
जिसके पास fd
पाइप के लिए इसके 3 खुले हैं wc
(हालांकि यह इसका कोई उपयोग नहीं कर रहा है, अकेले इसे लिखें)। भीतरी {
संभावना एक अतिरिक्त subshell प्रक्रिया है कि यह भी एक होगा कारण होगा fd
3 खुला और दोनों के लिए इंतजार करेंगे tee
और grep
।
इसका मतलब है कि बाहर निकलने के wc
बाद केवल अपनी लाइन नंबर लिखेंगे grep
।
क्या आपने इसे उचित तरीके से लिखा था, जो उन छड़ों को बंद करने से है जिनकी खुली जरूरत नहीं थी:
{ { <file.txt tee /dev/fd/3 4>&- |
grep LITERAL >&4 3>&- 4>&-; } 3>&1 | wc -l 4>&-;} 4>&1
तब आदेश शेल में गारंटी नहीं दी गई होगी जो उपधारा प्रक्रिया को अनुकूलित करती है। हालांकि, एकमात्र शेल जो मुझे पता है कि यह है, ksh93
लेकिन ksh93
पाइप के लिए सॉकेट जोड़े का उपयोग करता है , इसलिए /dev/fd/3
कम से कम लिनक्स पर वहां काम नहीं करेगा।
देखने के लिए क्या प्रक्रियाओं चल रहे हैं, तो आप बदल सकते हैं grep
के साथ 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
इसके साथ bash
, आप उस अतिरिक्त शेल प्रक्रिया को देख सकते हैं, और आप यह भी देख सकते हैं कि इसके साथ पाइप 3 पर खोला गया है:
$ (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>&-
मतलब है, fd 4 उपयोग और बंद दोनों प्रतीत होता है?