सवाल मैं लिनक्स में एकल इनपुट स्ट्रीम में दो नामित पाइपों में कैसे शामिल हो सकता हूं


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

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

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

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


59
2017-08-16 17:29


मूल




जवाब:


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

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

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

cat <(command1) <(command2) > outputfile

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

paste <(command1) <(command2) > outputfile

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

diff <(command1) <(command2) > outputfile

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

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

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

cat <(command1 & command2) > outputfile

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


94
2017-08-16 18:28



बहुत बढ़िया! मैंने बैश के मैनपेज को बहुत समय पढ़ा है लेकिन उसे वह नहीं चुना है - Javier
आप [उन्नत बैश स्क्रिप्टिंग गाइड] में संदर्भ पा सकते हैं (tldp.org/LDP/abs/html/process-sub.html) लिनक्स प्रलेखन परियोजना में - brice
आपने धमाल मचाया। धन्यवाद। - Steve Kehlet
मैं पाइपिंग द्वारा interleaved लाइनों को रोकने में सक्षम था grep --line-buffered - समवर्ती के लिए आसान grepआईएनजी tail एकाधिक लॉग फ़ाइलों का। देख stackoverflow.com/questions/10443704/line-buffered-cat - RubyTuesdayDONO


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

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

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

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


12
2017-08-16 17:43



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


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

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


8
2017-08-16 17:36



नोट: जब तक दोनों कमांड नहीं हैं () प्रत्येक लाइन पर अपने आउटपुट को फ्लश करें (और परमाणु के लिए कुछ अन्य अस्पष्ट POSIX नियम), आप बिल्ली के इनपुट पर कुछ अजीब scrambling के साथ खत्म हो सकता है ... - freiheit
क्या आप एम्पर्सेंड चरित्र के बजाय अर्धविराम का उपयोग नहीं कर रहे हैं? - Samir


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

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


4
2017-07-26 00:09



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


इस के लिए मैंने वास्तव में एक अच्छा कमान का उपयोग किया है 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
2018-01-24 07:34





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

पूंछ-एफ / टीएमपी / पी 1 / टीएमपी / पी 2>   / Tmp / आउटपुट

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

संपादित करें: unbuffered पढ़ने और नामित पाइप के लिए इष्टतमकरण:

विचार / tmp / p1, / ​​tmp / p2, / tmp / p3 नामित पाइप के रूप में, "mkfifo / tmp / p द्वारा निर्मितएन"

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

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

पूंछ-एफ / टीएमपी / पी 3

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

echo -n> / tmp / p1

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

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


3
2017-08-16 17:45



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


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

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

का उत्पादन देता है:

foo
bar
foo
bar

0
2018-05-11 22:16