बैश चर दायरा


104

कृपया मुझे समझाएं कि बहुत अंतिम echoवक्तव्य क्यों खाली है? मुझे उम्मीद है कि XCODE1 के मूल्य में लूप में वृद्धि हुई है:

#!/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`

और यह भी समय के बयान के बाहर मुद्रित नहीं होगा। मुझे लगता है कि मुझे यहाँ पर वेरिएबल स्कोप के बारे में कुछ याद आ रहा है, लेकिन ol का मैन पेज मुझे नहीं दिखा रहा है।


आप XCODE को किसी ऐसी चीज़ के लिए कहाँ से आरंभ कर सकते हैं जिसमें वृद्धि हो सकती है?
पॉल टॉम्बलिन

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

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

सहमत .. ऐसा लगता है कि यह "जबकि पढ़ा" लूप के साथ क्या करना है?
मैट पी

जवाबों:


117

क्योंकि आप लूप में पाइपिंग कर रहे हैं, जबकि लूप को चलाने के लिए एक सब-शेल बनाया गया है।

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

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

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


2
यह सिर्फ प्रतीत होता है यादृच्छिक मुद्दों के कई जवाब दिया मैं बैश पटकथा के साथ चल रहा था।
डैनियल अगंस

यह सही जवाब मुझे बहुत परेशान करता है और हमारे CI सिस्टम में एक बहुत ही अजीब व्यवहार के बारे में बताता है।
कायसी

108

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

आपके विशिष्ट उदाहरण को पाइप को फिर से लिखना करके हल किया जा सकता है

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

या शायद

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

32
उन लोगों के लिए जो इस उलझन को देख रहे हैं कि पूरा <() सिंटैक्स क्या है (जैसे मैं था), इसे "प्रोसेस सब्स्टीट्यूशन
रॉस ऐकेन

2
प्रक्रिया प्रतिस्थापन कुछ ऐसा है जो सभी को नियमित रूप से उपयोग करना चाहिए! यह सुपर उपयोगी है। मैं vimdiff <(grep WARN log.1 | sort | uniq) <(grep WARN log.2 | sort | uniq)हर दिन कुछ ऐसा करता हूं । विचार करें कि आप एक साथ कई का उपयोग कर सकते हैं और उन्हें फ़ाइलों की तरह व्यवहार कर सकते हैं ... POSSIBILITIES!
ब्रूनो ब्रोंस्की

8

यह भी काम करना चाहिए (क्योंकि प्रतिध्वनि और जबकि एक ही उपधारा में हैं):

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

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 एक आवश्यकता है (इसे स्थापित करें)। वैकल्पिक रूप से, आप xclip का उपयोग कर सकते हैं: xclip -i -selection clipboard इसके बजाय xsel -i -p


मुझे एक त्रुटि मिलती है: ./scraper.sh: पंक्ति 111: xsel: कमांड नहीं मिली ।/scraper.sh: पंक्ति 114: xsel: कमांड नहीं मिली
3kstc

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

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

देखें कि क्या वे परिवर्तन मदद करते हैं


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

0

एक अन्य विकल्प यह है कि परिणाम को उप फ़ाइल से फ़ाइल में आउटपुट करें और फिर इसे मूल शेल में पढ़ें। कुछ इस तरह

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

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" )

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

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