2008-09-23 22 views
87

कृपया मुझे बताएं कि आखिरी "गूंज" कथन खाली क्यों है? मैं उम्मीद है कि यह 1 का मान है, जबकि पाश में वृद्धि की गई थी:बैश वैरिएबल स्कोप

#!/bin/bash 
OUTPUT="name1 ip ip status" # normally output of another command with multi line output 

if [ -z "$OUTPUT" ] 
then 
     echo "Status WARN: No messages from SMcli" 
     exit $STATE_WARNING 
else 
     echo "$OUTPUT"|while read NAME IP1 IP2 STATUS 
     do 
       if [ "$STATUS" != "Optimal" ] 
       then 
         echo "CRIT: $NAME - $STATUS" 
         echo $((++XCODE)) 
       else 
         echo "OK: $NAME - $STATUS" 
       fi 
     done 
fi 

echo $XCODE 

मैं निम्नलिखित बयान के बजाय ++ Xcode विधि

XCODE=`expr $XCODE + 1` 

और यह भी अभ्यस्त प्रिंट का उपयोग कर की कोशिश की है वक्तव्य के बाहर। मुझे लगता है कि मैं यहाँ परिवर्तनीय दायरे के बारे में कुछ याद कर रहा हूं लेकिन ओल 'मैन पेज मुझे यह नहीं दिखा रहा है। अगर उन परिवर्तनों को मदद

+0

आप XCODE को उस चीज़ पर प्रारंभ करते हैं जिसे बढ़ाया जा सकता है? –

+0

मैंने कोड के शीर्ष पर "XCODE = 0" फेंकने की कोशिश की है, जबकि कथन के बिना –

+0

क्रॉफ्ट के बिना, यह मेरे लिए काम करता है। #!/Bin/bash मैं 1 2 3 4 5 में; echo $ ((++ XCODE)) किया गूंज "फिन:" $ XCODE मुझे लगता है कि आपकी समस्या में परिवर्तनीय स्कॉइंग और कुछ भी हो रहा है, जो कुछ भी हो रहा है उसके साथ करने के लिए कुछ भी नहीं है। –

उत्तर

91

क्योंकि आप जबकि लूप में पाइप रहे

+0

समझ में आता है .. धन्यवाद। ऐसा लगता है कि समारोह मेरे लिए जाने का तरीका है। –

+1

इसने बस इतने यादृच्छिक मुद्दों का उत्तर दिया कि मैं बैश स्क्रिप्टिंग के साथ चल रहा था। –

+0

यह सही उत्तर मुझे इतना परेशान करता है और हमारे सीआई सिस्टम में वास्तव में अजीब व्यवहार बताता है। – KayCee

1
#!/bin/bash 
OUTPUT="name1 ip ip status" 
+export XCODE=0; 
if [ -z "$OUTPUT" ] 
---- 

        echo "CRIT: $NAME - $STATUS" 
-     echo $((++XCODE)) 
+     export XCODE=$(($XCODE + 1)) 
      else 

echo $XCODE 

देखते हैं, एक उप खोल जबकि पाश को चलाने के लिए बनाया जाता है। अब इस बच्चे की प्रक्रिया में पर्यावरण की अपनी प्रति है और वैरिएबल को अपने माता-पिता को वापस नहीं दे सकती है (जैसा कि किसी भी यूनिक्स प्रक्रिया में है)।

इसलिए आपको पुनर्गठन की आवश्यकता होगी ताकि आप लूप में पाइप नहीं कर रहे हों। वैकल्पिक रूप से आप उदाहरण के लिए फ़ंक्शन में भाग सकते हैं और उस मान को प्रतिबिंबित कर सकते हैं जो उप प्रक्रिया से वापस लौटना चाहते हैं।

http://tldp.org/LDP/abs/html/subshells.html#SUBSHELL

+0

ऐसा करने पर, अब मुझे अंतिम इको स्टेटमेंट के लिए प्रिंट करने के लिए "0" मिलता है। हालांकि मुझे उम्मीद है कि मान 1 शून्य नहीं होगा। इसके अलावा, निर्यात का उपयोग क्यों? मुझे लगता है कि इसे पर्यावरण में मजबूर करता है? –

93

समस्या यह है कि एक पाइप के साथ एक साथ रखा प्रक्रियाओं subshells में क्रियान्वित कर रहे हैं (और इसलिए अपने स्वयं के वातावरण) है। while के भीतर जो कुछ भी होता है वह पाइप के बाहर कुछ भी प्रभावित नहीं करता है।

आपका विशिष्ट उदाहरण

while ... do ... done <<< "$OUTPUT" 

या शायद

while ... do ... done < <(echo "$OUTPUT") 
+1

शानदार। मैंने पहले <<वाक्यविन्यास नहीं देखा था, इसलिए इसे पढ़ना होगा, लेकिन यह एक इलाज करता है। शुरुआत के बजाए अंत में इनपुट कमांड होना अजीब लगता है, लेकिन यह काम करता है। – Jonathan

+3

मुझे '<(कमांड)' वाक्यविन्यास भी नहीं पता था, और इसने मुझे बहुत समय और सिरदर्द बचाया है। आप श्रीमान :) –

+26

के लिए एक बड़ा +1 कौन क्या पूरे <() वाक्य रचना है (जैसे मैं था) के रूप में इस उलझन में पर देख रहे हैं उन लोगों के लिए है, यह "प्रक्रिया प्रतिस्थापन" कहा जाता है, और विशिष्ट ऊपर विस्तृत उपयोग किया जा सकता है यहां देखा गया: http://mywiki.wooledge.org/ProcessSubstitution –

0

एक अन्य विकल्प उत्पादन करने के लिए है करने के लिए पाइप दोबारा लिख ​​कर हल किया जा सकता subshell से और फिर एक फ़ाइल में परिणामों में इसे पढ़ा पैरेंट खोल

#!/bin/bash 
EXPORTFILE=/tmp/exportfile${RANDOM} 
cat /tmp/randomFile | while read line 
do 
    LINE="$LINE $line" 
    echo $LINE > $EXPORTFILE 
done 
LINE=$(cat $EXPORTFILE) 
3

एक और विकल्प की तरह कुछ:

#!/bin/bash 
cat /some/file | while read line 
do 
    var="abc" 
    echo $var | xsel -i -p # redirect stdin to the X primary selection 
done 
var=$(xsel -o -p) # redirect back to stdout 
echo $var 

संपादित करें: यहाँ, xsel एक आवश्यकता (इसे स्थापित) है। यह रूप में अच्छी तरह से काम करना चाहिए (क्योंकि गूंज और, जबकि एक ही subshell में हैं) xsel -i -p

+0

मैं एक त्रुटि मिलती है: ./scraper.sh: लाइन 111: xsel: आदेश नहीं मिला ./scraper.sh: लाइन 114: xsel: आदेश नहीं मिला – 3kstc

+0

@ 3kstc जाहिर है, xsel स्थापित करें। इसके अलावा, आप एक्सक्लिप का उपयोग कर सकते हैं, लेकिन इसका उपयोग थोड़ा अलग है। मुख्य यहाँ बिंदु: 1 आप एक क्लिपबोर्ड (linux में उनमें से 3) में उत्पादन में डाल दिया, 2 - आप उसे वहां से हड़पने और stdout के लिए भेज देते हैं। – Rammix

4

के बजाय xclip -i -selection clipboard : वैकल्पिक रूप से, आप xclip उपयोग कर सकते हैं

#!/bin/bash 
cat /tmp/randomFile | (while read line 
do 
    LINE="$LINE $line" 
done && echo $LINE) 
0

मैं इस के चारों ओर हो गया, जब मैं कर रहा था अपने ही छोटे डु:

ls -l | sed '/total/d ; s/ */\t/g' | cut -f 5 | 
(SUM=0; while read SIZE; do SUM=$(($SUM+$SIZE)); done; echo "$(($SUM/1024/1024/1024))GB") 

बिंदु, कि मैं के साथ एक subshell) बनाने के (मेरे योग चर और जब युक्त लेकिन मैं पूरी तरह से() के बजाय पूरी तरह से पाइप करता हूं, जो गॉचा से बचाता है।

संबंधित मुद्दे