ব্যাশ ভেরিয়েবলের সুযোগ


104

আমাকে দয়া করে ব্যাখ্যা করুন কেন খুব শেষ echoবিবৃতিটি ফাঁকা? আমি প্রত্যাশা করি যেটি XCODEযখন লুপের সাথে 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`

এবং এটিও যদিও বিবৃতিটির বাইরে মুদ্রণ করবে না। আমার মনে হয় আমি এখানে পরিবর্তনশীল স্কোপ সম্পর্কে কিছু অনুভব করছি তবে ওলম্যানের পৃষ্ঠাটি এটি আমাকে দেখায় না।


আপনি কোথায় বাড়ানো যেতে পারে এমন কোনও ক্ষেত্রে XCODE সূচনা করবেন?
পল টমবলিন

আমি বিবৃতিটির বাইরে কোডের শীর্ষে একটি "XCODE = 0" ফেলে দেওয়ার চেষ্টা করেছি
ম্যাট পি

ক্রাফট ছাড়া এটি আমার পক্ষে কাজ করে। #! / বিন / বাশ আমার জন্য 1 2 3 4 5; ইকো করুন $ ((++ এক্সকোডি)) ইকো করেছেন "ফিন:" $ এক্সকোডি আমি মনে করি আপনার সমস্যার পরিবর্তনশীল স্কোপিং এবং কিছু সময়ের মধ্যে যা ঘটছে তার সাথে কিছুই করার নেই।
পল টমলিন

রাজি হয়ে গেছে .. দেখে মনে হচ্ছে এটি "পড়ার সময়" লুপটির সাথে কি করতে হবে?
ম্যাট পি

এই সম্পর্কে একটি বাশ এফকিউ রয়েছে
ফ্যাবিও বলেছেন

উত্তর:


117

আপনি যখন লুপটিতে পাইপ করছেন, ততক্ষণ লুপটি চালানোর জন্য একটি উপ-শেল তৈরি করা হবে।

এখন এই শিশু প্রক্রিয়াটির পরিবেশের নিজস্ব অনুলিপি রয়েছে এবং কোনও অভিভাবক তার পিতামাতার কাছে ফিরে যেতে পারে না (কোনও ইউনিক্স প্রক্রিয়া হিসাবে)।

সুতরাং আপনাকে পুনর্গঠন করতে হবে যাতে আপনি লুপের মধ্যে পাইপিং করেন না। বিকল্প হিসাবে আপনি একটি ফাংশন চালাতে পারেন, উদাহরণস্বরূপ, এবং echoআপনি উপ-প্রক্রিয়া থেকে ফিরে আসা মানটি চান।

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


2
এটি কেবল এতটা আপাতদৃষ্টিতে এলোমেলো সমস্যাগুলির উত্তর দিয়েছিল যার মধ্যে আমি ব্যাশ স্ক্রিপ্টিংটি নিয়ে চলছিলাম।
ড্যানিয়েল অ্যাগস

এই নিখুঁত উত্তরটি আমাকে খুব বিরক্ত করে এবং আমাদের সিআই সিস্টেমে একটি সত্যই অদ্ভুত আচরণের ব্যাখ্যা দেয়।
কায়সি

108

সমস্যাটি হ'ল পাইপের সাথে একসাথে রাখা প্রক্রিয়াগুলি সাব-শেলগুলিতে কার্যকর করা হয় (এবং সেইজন্য তাদের নিজস্ব পরিবেশ রয়েছে)। এর মধ্যে যা ঘটে whileতা পাইপের বাইরের কিছুকে প্রভাবিত করে না।

আপনার নির্দিষ্ট উদাহরণটি পাইপটিতে পুনরায় লেখার মাধ্যমে সমাধান করা যেতে পারে

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

অথবা সম্ভবত

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

32
যারা পুরো <() সিনট্যাক্সটি (যেমন আমি ছিলাম) কী তা নিয়ে বিভ্রান্তির দিকে তাকাচ্ছেন, তাদের "প্রসেস সাবস্টিটিউশন" বলা হয় এবং উপরে বর্ণিত নির্দিষ্ট ব্যবহারটি এখানে দেখা যেতে পারে: mywiki.wooledge.org/ProcessSubstedia
রস একেন

2
প্রক্রিয়া সাবস্টিটিউশন এমন কিছু যা নিয়মিতভাবে ব্যবহার করা উচিত! এটি সুপার দরকারী। আমি vimdiff <(grep WARN log.1 | sort | uniq) <(grep WARN log.2 | sort | uniq)প্রতিদিনের মতো কিছু করি । বিবেচনা করুন যে আপনি একবারে একাধিক ব্যবহার করতে পারেন এবং তাদের ফাইলগুলির মতো চিকিত্সা করতে পারেন ... পজিটিবিলিটিস!
ব্রুনো ব্রোনোস্কি

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 ইনস্টল করুন। এছাড়াও, আপনি এক্সক্লিপ ব্যবহার করতে পারেন তবে এর ব্যবহার কিছুটা আলাদা। এখানে মূল বক্তব্য: 1 ম আপনি আউটপুটটি একটি ক্লিপবোর্ডে রেখেছেন (এর মধ্যে 3 টি লিনাক্সে), আপনি এটি সেখান থেকে ধরেন এবং স্টাডাউটে প্রেরণ করেন।
র‌্যামমিক্স

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" পাই তবে আমি মানটি শূন্য নয় 1 হতে আশা করি। এছাড়াও, রফতানি ব্যবহার কেন? আমি ধরে নিই যে এটি পরিবেশে বাধ্য করে?
ম্যাট পি

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

আমি যখন আমার নিজের ছোট্ট du তৈরি করছিলাম তখন আমি এটিকে ঘিরে ফেলেছিলাম:

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

মুল বক্তব্যটি হ'ল আমি (এস) এর সাথে আমার এসএমএম ভেরিয়েবল এবং কিছুটি অন্তর্ভুক্ত করে একটি সাবশেল তৈরি করি তবে আমি নিজেই কিছুক্ষণের পরিবর্তে পুরো () টি পাইপ করি যা গোচা এড়িয়ে চলে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.