प्रक्रिया प्रतिस्थापन के साथ आउटपुट ऑर्डर


11

यह वह है जो मैं आमतौर पर चलाने के लिए grepऔर wcएक फाइल पर दो बार स्कैन किए बिना करता हूं

<file.txt  tee >(grep LITERAL) >(wc -l) >/dev/null

हालाँकि, इससे पैदावार होती है

EXEC LITERAL
32

कभी-कभी और

32
EXEC LITERAL

बाकी समय पर। ( पहले उदाहरण grepसे आउटपुट wcनिकलता है और दूसरे में इसके विपरीत।)

दूसरी ओर, पुनर्निर्देशन और फ़ाइल विवरणक के साथ

{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1 

मुझे हमेशा लगता है

EXEC LITERAL
32

मैं पसंद करता हूं कि आउटपुट ऑर्डर अनुमानित हो लेकिन क्या यह दूसरे दृष्टिकोण के साथ गारंटी है?

जवाबों:


4

दोनों मे

<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 प्रक्रिया है कि यह भी एक होगा कारण होगा fd3 खुला और दोनों के लिए इंतजार करेंगे 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 उपयोग और बंद दोनों प्रतीत होता है?
इरुवर

@ 1_CR, के बाद >&4, के लिए छोटा है 1>&4, grepएक ही संसाधन के लिए 1 और 4 बिंदु (शेल का प्रारंभिक स्टडआउट)। grepकुछ भी करने के लिए अपने fd 4 खुला होने की जरूरत नहीं है। यह इसके साथ कुछ नहीं करता है, इसलिए हम इसे बंद कर देते हैं4>&-
स्टीफन चेज़लस

वह अंतिम कमांड-लाइन क्रिप्टिक मैजिक है।

-1

एक पूर्वानुमान आदेश का उपयोग करने के लिए

(<file.txt  tee >(grep LITERAL) >(wc -l) >/dev/null)|sort

शायद मैं पर्याप्त स्पष्ट नहीं था। मेरा मतलब था कि कमांड आउटपुट के ऑर्डर के संदर्भ में अनुमानित ऑर्डर (यानी wc से आउटपुट से पहले grep से आउटपुट)। मुझे संयुक्त आउटपुट सॉर्ट की आवश्यकता नहीं है
1947

बस पाया गया gnu.org/software/bash/manual/bashref.html#Command-Grouping , यह मुझे बताता है कि {} ऑपरेटर के साथ आप यह सुनिश्चित करते हैं (इस मामले में) कि आप पहली बार <file.txt टी / देव / fd करें / ३ | grep LITERAL> & 4; और जब यह किया जाता है तो आप wc को कॉल करते हैं, इसलिए अपने मूल प्रश्न का उत्तर देने के लिए, हाँ यह मेरी समझ की गारंटी है
Thorsten Staerk

1
@ThorstenStaerk क्या आप अपने उत्तर में मिली अतिरिक्त जानकारी जोड़ सकते हैं?
terdon

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.