बैश: प्रक्रिया प्रतिस्थापन और स्टड


13

निम्नलिखित पंक्ति स्पष्ट है:

echo "bla" | foo | bar

लेकिन क्या नीचे वाले भी ऐसा ही करते हैं?

echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)

स्टड से कौन सा fooऔर bar"ब्ला" पढ़ा और क्यों?

मेरा मतलब है कि निश्चित रूप से, मैं बस इसे कोड कर सकता हूं और इसकी जांच कर सकता हूं, लेकिन मुझे यकीन नहीं है कि यह परिभाषित व्यवहार है या मैं उन विशेषताओं का शोषण कर रहा हूं जिन पर मुझे भरोसा नहीं करना चाहिए।

जवाबों:


9

यह शेल पर निर्भर है और AFAICS का दस्तावेज नहीं है। में kshऔर bash, पहले मामले में, fooके रूप में ही stdin साझा करेंगे bar। वे के आउटपुट के लिए लड़ेंगे echo

तो उदाहरण के लिए,

$ seq 10000 | paste - <(tr 1 X)'
1       X
2       X042
3       X043
4       X044
5       X045
[...]

आप सबूत देखते हैं कि pasteपाठ के हर दूसरे ब्लॉक को seqआउटपुट से trपढ़ता है जबकि दूसरे को पढ़ता है।

इसके साथ zsh, इसे बाहरी स्टड मिलता है (जब तक कि यह टर्मिनल नहीं है और शेल इंटरएक्टिव नहीं है, जिस स्थिति में यह पुनर्निर्देशित है /dev/null)। ksh(जहां इसकी उत्पत्ति हुई), zshऔर bashप्रक्रिया प्रतिस्थापन AFAIK के समर्थन के साथ एकमात्र बॉर्न-जैसे गोले हैं।

में echo "bla" | bar < <(foo), ध्यान दें कि barस्टड के आउटपुट द्वारा खिलाया जाने वाला पाइप होगा foo। यह अच्छी तरह से परिभाषित व्यवहार है। उस स्थिति में, ऐसा प्रतीत होता है कि fooस्टड वह पाइप है echoजो सभी के द्वारा खिलाया जाता है ksh, zshऔर bash

यदि आप चाहते हैं कि सभी तीनों गोले में एक सुसंगत व्यवहार हो और भविष्य के प्रमाण हों, क्योंकि व्यवहार बदल सकता है क्योंकि यह दस्तावेज नहीं है, तो मैं लिखूंगा:

echo bla | { bar <(foo); }

यह सुनिश्चित करने के लिए कि fooस्टड भी पाइप है echo(मैं यह नहीं देख सकता कि आप ऐसा क्यों करना चाहते हैं)। या:

echo bla | bar <(foo < /dev/null)

सुनिश्चित करें कि fooहै नहीं से पाइप से पढ़ा echo। या:

{ echo bla | bar 3<&- <(foo <&3); } 3<&0

करवाने के लिए foo'के वर्तमान संस्करण में की तरह बाहरी stdin stdin है zsh


"उस मामले में, फू का स्टड, ksh, zsh और bash के सभी में गूंज द्वारा खिलाया गया पाइप है।" आपने अभी-अभी इसे हाथ से परीक्षण किया है, या यह कहीं प्रलेखित है?
etam1024

पहली पंक्ति में "पहले मामले में" का उल्लेख करता है `| फू | बार `या` | बार <(फू) `?
वोल्कर सेगेल

4

echo "bla" | foo | bar: के आउटपुट echo "bla"को रीडायरेक्ट किया जाता है foo, जिसके आउटपुट को रीडायरेक्ट किया जाता है bar

echo "bla" | bar <(foo): कि एक के उत्पादन के echo "bla"लिए पाइप bar। लेकिन barएक तर्क के साथ निष्पादित किया जाता है। तर्क फ़ाइल डिस्क्राइटर का रास्ता है, जहां के आउटपुट को fooभेजा जाएगा। यह तर्क उस फ़ाइल की तरह व्यवहार करता है जिसमें आउटपुट होता है foo। तो, यह वही नहीं है।

echo "bla" | bar < <(foo): कोई यह मान सकता है कि आउटपुट को echo "bla"भेजा जाना चाहिए barऔर पूरा विवरण पहले वाले के बराबर है। लेकिन, यह सही नहीं है। निम्न होता है: क्योंकि इनपुट पुनर्निर्देशन <पाइप ( |) के बाद किया जाता है , यह इसे अधिलेखित कर देता है । तो echo "bla"बार करने के लिए पाइप नहीं है। इसके बजाय के fooमानक मानक इनपुट के रूप में पुनर्निर्देशित किया जाता है bar। इसे साफ़ करने के लिए निम्नलिखित कमांड और आउटपुट देखें:

$ echo "bla" | cat < <(echo "foo")
foo

जैसा कि आप देख रहे हैं echo "bla"द्वारा superseded है echo "foo"

अब इस कमांड को देखें:

$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo

तो echo "bar"पाइप किया जाता है awk, जो स्टड को पढ़ता है और स्ट्रिंग and fooको आउटपुट में जोड़ता है । इस आउटपुट को पाइप किया जाता है cat


और मेरा प्रश्न है: "क्या तथ्य यह है कि awk" बार "एक परिभाषित व्यवहार पढ़ता है?"
etam1024

हाँ यही है। cmd1 < <(cmd2)जैसा व्यवहार करता है cmd2 | cmd1
अराजकता

या के cmd1 | cmd2 | cmd3रूप में ही हैcmd1 | cmd3 < <(cmd2)
अराजकता

3
अगर यह विकिपीडिया होता तो मैं आपके बयानों पर "उद्धरण आवश्यक" टैग लगाता :) मेरे सवाल का पूरा मुद्दा यह है कि यह आपके कहे अनुसार काम करता है, लेकिन मुझे इसके बारे में कोई दस्तावेज नहीं मिला।
etam1024
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.