2011-04-22 18 views
8

संपादित करें:पाइप के बाईं तरफ सबहेल है?

sed '[email protected]^@ @' <(f1) के बारे में नीचे दी गई मेरी टिप्पणी गलत $BASH_SUBSHELL इंगित करता है कि हम प्रक्षेपण के रूप में एक ही स्तर में, चर मुख्य लिपि में खो जाते हैं कर रहे हैं। गॉर्डन्स उत्तर के आधार पर मैंने f1 > >(sed '[email protected]^@ @') का परीक्षण किया और ऐसा लगता है कि यह सही तरीके से काम करता है। फिर भी, पहले फार्म के लिए BASH_SUBSHELL 1 और 0 नहीं होना चाहिए?

In f1, SUBSHELL: 0, i=1 
In f1, SUBSHELL: 1, i=2 
at end, i=1 

(sed का उद्देश्य सिर्फ कुछ करने के लिए एक पाइप के लिए है, यह उम्मीद नहीं करते:


यह छोटी परीक्षण

#!/bin/bash 
declare -i i=0 
function f1() 
{ 
    let i++ 
    echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2 
} 

f1 
f1 | sed '[email protected]^@  @' 

echo "at end, i=$i" 
निम्नलिखित उत्पादन के साथ

पर विचार करें कुछ भी करने के लिए क्योंकि f1 आउटपुट stderr के लिए)

फ़ंक्शन f1 वर्तमान BASH_SUBSH लॉग करता है ELL और की मैं

मैं जानता हूँ कि क्यों स्क्रिप्ट के अंत में हम i=1 मिल वर्तमान मूल्य, इसकी वजह से दूसरे मंगलाचरण एक subshell में था, और subshell 1 पर मैं के मूल्य खो गया था।

क्या मैं नहीं जानता कि क्यों पाइप के बाईं ओर वर्तमान खोल

हालांकि मैं लगा मुझे पता है क्यों बाईं ओर है साथ sed '[email protected]^@ @' <(f1) मैं चाहते हैं इससे बचने के सकता है कि में मार डाला नहीं किया गया है मुख्य स्क्रिप्ट

+0

मुझे लगता है कि खोल को पाइप के दोनों सिरों को सबहेल – sehe

+0

में रखने की अनुमति है एक त्वरित Google ने यह पाया: http://www.linuxprogrammingblog.com/pipe-in-bash-can-be-a-trap –

+0

@ ब्रायन कि लेख पाइप के बाएं तरफ चर्चा नहीं करता है ...मुझे पहले से ही पता है कि यह पाइप – nhed

उत्तर

12

bash man page से समान स्तर पर नहीं: "पाइपलाइन में प्रत्येक कमांड को एक अलग प्रक्रिया (यानी, सबहेल में) के रूप में निष्पादित किया जाता है।" मुझे लगता है कि वर्तमान खोल में एक पाइपलाइन के एक घटक को निष्पादित करना संभव होगा (यानी पहला, या आखिरी, या शायद बीच में एक), यह इस तरह पसंदीदा नहीं खेलता है: वे सभी सबशेल्स में निष्पादित करते हैं । आप इस तरह से अपनी स्क्रिप्ट को संशोधित करते हैं:

#!/bin/bash 
declare -i i=0 
function f1() 
{ 
    let i++ 
    echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2 
} 

f1 
f1 | f1 | f1 

echo "at end, i=$i" 

यह प्रिंट: एफ 1 के

सभी 3 क्योंकि
In f1, SUBSHELL: 0, i=1 
In f1, SUBSHELL: 1, i=2 
In f1, SUBSHELL: 1, i=2 
In f1, SUBSHELL: 1, i=2 
at end, i=1 

आमंत्रण subshells में पाइपलाइन समय में।

+0

के दाहिने तरफ परिवर्तनीय असाइनमेंट के लिए बुरी खबर है। मुझे लगता है कि मेरा भ्रम पाइप की सोच से आता है और फाइल रीडायरेक्शन कुछ हद तक बराबर है 'f1 nhed

+0

@nhed करना होगा: मैं एक आउटपुट पुनर्निर्देशन की तरह एक पाइप के बारे में नहीं सोचूंगा। एक पाइपलाइन I/O पुनर्निर्देशन द्वारा एकत्रित आदेशों की एक श्रृंखला है, और सभी एक साथ चलते हैं; चूंकि शेल मल्टीटास्किंग नहीं करता है, इसलिए यह मुख्य शेल में उनमें से अधिकतर में चला सकता है, और चूंकि वे मूल रूप से बराबर हैं, इसलिए मुख्य खोल में भाग लेने के लिए कोई भी कारण नहीं है, इसलिए निष्पक्षता के लिए वे सभी हैं subshells में भागो। बैश में, आप कुछ आदेशों को संक्षेप में कम करने के लिए '< <()' and '>>()' का उपयोग कर सकते हैं, जिससे एक कमांड मुख्य खोल में चलने की इजाजत देता है। –

+3

@nhed: (जारी) उदाहरण के लिए, मुख्य खोल में चलाने के लिए पाइपलाइन में पहले कमांड को मजबूर करने के लिए, 'cmd1>> (cmd2 | cmd3 | ...)' का उपयोग करें। मुख्य खोल में cmd2 चलाने के लिए, 'cmd2 < <(cmd1) >> (cmd3 | ...) ', आदि –

-1

यहाँ एक बहुत संक्षिप्त उदाहरण है अगर किसी को परवाह नहीं है:

cd/&& cd /tmp/ | pwd ; pwd 
/
/

या:

cd/&& cd /tmp/ | cd /var/ ; pwd 
/

हाँ यह पेज यह सब

http://linux.die.net/man/1/bash# एक पाइप लाइन में प्रत्येक कमांड एक के रूप में क्रियान्वित किया जाता है कहते हैं अलग प्रक्रिया (यानी, एक सबहेल में)।