मैं लिनक्स में सिंगल इनपुट स्ट्रीम में दो नामित पाइपों को कैसे जोड़ूं


64

|लिनक्स में पाइप ( ) सुविधा का उपयोग करके मैं एक या कई आउटपुट धाराओं के लिए मानक इनपुट को आगे बढ़ा सकता हूं।

मैं teeउप प्रक्रियाओं को अलग करने के लिए आउटपुट को विभाजित करने के लिए उपयोग कर सकता हूं ।

क्या दो इनपुट धाराओं में शामिल होने की आज्ञा है?

मैं इसे किस तरह लूं? काम कैसे करता है?

जवाबों:


105

व्यक्तिगत रूप से, मेरा पसंदीदा (अधिकांश लिनक्स वितरण पर मानक और अन्य चीजों की आवश्यकता है)

यह विवरण बहुत कुछ निर्भर कर सकता है कि दो चीजें क्या उत्पादन करती हैं और आप उन्हें कैसे मर्ज करना चाहते हैं ...

आउटपुट में एक दूसरे के बाद कमांड 1 और कमांड 2 की सामग्री:

cat <(command1) <(command2) > outputfile

या यदि दोनों एक ही डेटा के वैकल्पिक संस्करणों को आउटपुट करते हैं, जिसे आप अगल-बगल देखना चाहते हैं (मैंने इसे snmpwalk के साथ प्रयोग किया है; एक तरफ संख्या और दूसरे पर MIB नाम):

paste <(command1) <(command2) > outputfile

या यदि आप दो समान कमांड के आउटपुट की तुलना करना चाहते हैं (दो अलग-अलग निर्देशिकाओं पर एक खोज कहें)

diff <(command1) <(command2) > outputfile

या अगर वे किसी प्रकार के आउटपुट का आदेश देते हैं, तो उन्हें मर्ज करें:

sort -m <(command1) <(command2) > outputfile

या दोनों आदेशों को एक साथ चलाएं (हालांकि, चीजों को थोड़ा-थोड़ा कर सकते हैं):

cat <(command1 & command2) > outputfile

<() ऑपरेटर प्रत्येक कमांड के लिए नामित पाइप (या / dev / fd फ़ाइलहैंडल संदर्भ) में उस कमांड के आउटपुट को पाइप करते हुए एक नामांकित पाइप (या / dev / fd) सेट करता है और कमांडलाइन पर नाम को पारित करता है। > () के साथ एक बराबर है। आप ऐसा कर सकते हैं: command0 | tee >(command1) >(command2) >(command3) | command4उदाहरण के लिए, एक साथ 4 अन्य कमांड के आउटपुट को एक साथ भेजना।


बहुत बढ़िया! मैंने बैश के मैनपेज को बहुत समय तक पढ़ा है, लेकिन उस एक
जेवियर

2
आप लिनक्स दस्तावेज़ परियोजना में [एडवांस बैश स्क्रिप्टिंग गाइड] ( tldp.org/LDP/abs/html/process-sub.html ) में संदर्भ पा सकते हैं
brice

3
मैं के माध्यम से पाइप द्वारा interleaved लाइनों को रोकने के लिए कर रहा था grep --line-bufferedसमवर्ती के लिए आसान - grep'ing tailएकाधिक लॉग फ़ाइलों की। देखें stackoverflow.com/questions/10443704/line-buffered-cat
RubyTuesdayDONO

16

catगोरिल्ला शो के रूप में आप दूसरे के साथ दो स्टीम जोड़ सकते हैं ।

आप एक FIFO भी बना सकते हैं, उस पर कमांड के आउटपुट को निर्देशित कर सकते हैं, फिर FIFO से जो भी अन्य प्रोग्राम है, उसे पढ़ें:

mkfifo ~/my_fifo
command1 > ~/my_fifo &
command2 > ~/my_fifo &
command3 < ~/my_fifo

उन प्रोग्रामों के लिए विशेष रूप से उपयोगी है जो केवल एक फ़ाइल लिखेंगे या पढ़ेंगे, या केवल एक दूसरे के साथ आउटपुट stdout / फ़ाइल को जोड़ने वाले प्रोग्राम को मिलाएगा जो केवल दूसरे का समर्थन करता है।


2
यह एक pfSense (फ्रीबीएसडी) पर काम करता है जबकि स्वीकृत उत्तर नहीं देता है। धन्यवाद!
नाथन

9
(tail -f /tmp/p1 & tail -f /tmp/p2 ) | cat > /tmp/output

/tmp/p1और /tmp/p2आपके इनपुट पाइप हैं, जबकि /tmp/outputआउटपुट है।


6
नोट: जब तक दोनों कमांड्स ()हर लाइन पर अपने आउटपुट को फ्लश नहीं करती हैं (और कुछ अन्य अस्पष्ट एटमॉसिटी के लिए नियम), आप बिल्ली पर इनपुट पर कुछ अजीब तरह से हाथापाई के साथ समाप्त हो सकते हैं ...
फ्रीशीट 16:10

क्या आपको एम्परसेंड चरित्र के बजाय अर्धविराम का उपयोग नहीं करना चाहिए?
समीर

यह महाकाव्य सामग्री है
मोबिजिटल

5

मैंने इसके लिए विशेष कार्यक्रम बनाया है: fdlinecombine

यह कई पाइपों (आमतौर पर प्रोग्राम आउटपुट) को पढ़ता है और उन्हें अलंकृत करने के लिए लिखता है (आप विभाजक को भी ओवरराइड कर सकते हैं)


विज्ञापित के रूप में काम करता है। इसे सार्वजनिक करने के लिए धन्यवाद।
अलेयी

3

एक बहुत अच्छी कमांड जो मैंने इसके लिए इस्तेमाल की है tpipe, आपको इसे संकलित करने की आवश्यकता हो सकती है क्योंकि यह आम नहीं है। यह वास्तव में आपके बारे में बात करने के लिए बहुत अच्छा है, और यह इतना साफ है कि मैं आमतौर पर इसे स्थापित करता हूं। मैन पेज यहाँ स्थित है http://linux.die.net/man/1/tpipe । वर्तमान में सूचीबद्ध डाउनलोड इस संग्रह http://www.eurogaran.com/downloads/tpipe/ पर है

यह इस तरह प्रयोग किया जाता है,

## Reinject sub-pipeline stdout into standard output:
$ pipeline1 | tpipe "pipeline2" | pipeline3

3

यहां सावधान रहें; बस उन्हें पूरा करना उन तरीकों से परिणामों को मिलाना होगा जो आप नहीं चाहते हैं: उदाहरण के लिए, यदि वे लॉग फाइलें हैं तो आप वास्तव में एक लाइन से आधे रास्ते में एक लाइन दूसरे से नहीं चाहते हैं। अगर ठीक है, तो

पूंछ -f / tmp / p1 / tmp / P2> / tmp / आउटपुट

काम करेगा। यदि यह ठीक नहीं है , तो आपको कुछ ऐसा करना होगा जो लाइन बफ़रिंग करेगा और केवल आउटपुट पूर्ण लाइनें देगा। Syslog ऐसा करता है, लेकिन मुझे यकीन नहीं है कि और क्या हो सकता है।

संपादित करें: असंबद्ध पढ़ने और नामित पाइपों के लिए अनुकूलन:

नामांकित / tmp / p1, / ​​tmp / P2, / tmp / p3 जैसा कि नामित पाइप, "mkfifo / tmp / p N " द्वारा बनाया गया

tail -q -f / tmp / p1 / tmp / P2 | awk '{प्रिंट $ 0> "/ tmp / p3"; करीब ( "/ tmp / p3"); fflush ();} '&

अब इस तरह से, हम उत्पादन नामित पाइप "/ tmp / p3" पढ़ सकते हैं unbuffered द्वारा:

पूंछ -f / tmp / p3

सॉर्ट का छोटा बग है, आपको 1 इनपुट पाइप / tmp / p1 द्वारा "इनिशियलाइज़" करने की आवश्यकता है:

इको-एन> / टीएमपी / पी १

पूंछ करने के लिए पहले 2 पाइप / tmp / p2 से इनपुट स्वीकार करेंगे और कुछ / tmp / p1 के आने तक प्रतीक्षा न करें। यह मामला नहीं हो सकता है, यदि आप सुनिश्चित हैं, तो / tmp / p1 पहले इनपुट प्राप्त करेगा।

इसके अलावा -q विकल्प की जरूरत है ताकि पूंछ फ़ाइलनामों के बारे में कचरा न छपे।


अधिक उपयोगी हो जाएगा: "टेल -q -f / tmp / p1 / tmp / P2 | एक और_कम" जैसा कि यह लाइन द्वारा लाइन किया जाएगा और -q विकल्प के साथ यह किसी भी अन्य कचरा प्रिंट नहीं करेगा
रेडब्लू

असंबद्ध फ़ाइल / नामित पाइप उपयोग के लिए: tail -q -f /tmp/p1 /tmp/p2 | awk '{print $0 > "/tmp/p3"; close("/tmp/p3"); fflush();}' & अब / tmp / p3 को पाइप का नाम भी दिया जा सकता है और आप इसे पढ़ सकते हैं बस यह tail -f /tmp/p3सब UNBUFFERED = लाइन द्वारा लाइन है हालांकि वहाँ सॉर्ट का छोटा बग है। पहली फ़ाइल / नामित पाइप को पहले क्रम में शुरू करने की आवश्यकता है पूंछ में 2 से आउटपुट स्वीकार करेंगे। तो आप की जरूरत है echo -n > /tmp/p1और सब कुछ की तुलना में आसानी से काम करेंगे।
तैयारब्लू

1

ऐसा करने के लिए सबसे अच्छा कार्यक्रम है lmerge। Freihart के उत्तर के विपरीत यह लाइन-ओरिएंटेड है इसलिए दो कमांड का आउटपुट एक दूसरे को क्लोब नहीं करेगा। अन्य समाधानों के विपरीत यह इनपुट को काफी विलीन कर देता है ताकि कोई कमांड आउटपुट पर हावी न हो सके। उदाहरण के लिए:

$ lmerge <(yes foo) <(yes bar) | head -n 4

का आउटपुट देता है:

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