बाश में दो तारों की तुलना


22

ifमेरी बैश स्क्रिप्ट में निम्नलिखित ब्लॉक हैं:

if [ ${PACKAGENAME} -eq kakadu-v6_4-00902C ]; then
  echo "successfully entered if block!!"
fi

स्क्रिप्ट निष्पादन मेरे ifब्लॉक में प्रवेश नहीं कर रहा है, भले ही $PACKAGENAMEइसके बराबर हो kakadu-v6_4-00902C। मैं क्या गलत कर रहा हूं?


9
-eqपूर्णांक के लिए सही है, आप एक स्ट्रिंग या रेगेक्स ( ==या =~) के लिए परीक्षण करना चाहते हैं : mywiki.wooledge.org/BashGuide/TestsAndConditionals
jasonwryan

धन्यवाद jasonwryanमैं इस संसाधन पर एक नज़र डालूँगा!
डेमीशीप

जवाबों:


31

-eq एक अंकगणितीय ऑपरेटर है, जो दो संख्याओं की तुलना करता है।

उपयोग =(पोर्टेबल / मानक sh), =~या ==इसके बजाय।

उद्धरणों का भी उपयोग करें, क्योंकि यदि ${PACKAGENAME}एक व्हाट्सएप या वाइल्डकार्ड वर्ण शामिल है, तो इसे कई तर्कों में विभाजित किया जाएगा, जिसके कारण [वांछित से अधिक तर्क देखने को मिलते हैं। यहां देखें आम बैश नुकसान की एक सूची।

if [ "${PACKAGENAME}" = 'kakadu-v6_4-00902C' ]; then
    echo "successfully entered if block!!"
fi

देखें man bash, खोज ( /) के लिए CONDITIONAL EXPRESSIONS


1
आह! धन्यवाद! इसने काम कर दिया! मैं स्पष्ट रूप से इस पर एक धोखेबाज़ हूँ। मैं आपकी मदद के लिए आभारी हूँ!
डेमीशीप

2
क्या आपने tldp.org/LDP/Bash-Beginners-Guide/html पर एक नज़र डाली है ? यह बहुत अच्छा बैश गाइड है और आपको उदाहरण और परीक्षा के साथ मदद करेगा :)।
पॉलिम

1
धन्यवाद polymमैं एक नज़र डालूँगा, संसाधन के लिए धन्यवाद! मैं अपने VI गाइड के बगल में वह टैब खोलूंगा। :)
डेमशीप

4
डबल कोष्ठक के भीतर, कोई शब्द विभाजन नहीं किया जाता है, इसलिए [[ $PACKAGENAME == "kakadu..." ]]ठीक है।
ग्लेन जैकमैन

4
@glennjackman खबरदार, भले ही डबल कोष्ठक के भीतर, आपको दाईं ओर के चर विस्तार के आसपास दोहरे उद्धरण चिह्नों की आवश्यकता है =, ==और !=, क्योंकि वह पक्ष एक पैटर्न है, न कि एक स्ट्रिंग। उदाहरण के लिए, foo='*'; [[ whatever = $foo ]]सत्य है।
गिल्स एसओ- बुराई को रोकना '

6

बदलें -eqके साथ == तो अपने अगर ब्लॉक इस होगी: -

if [ ${PACKAGENAME} == kakadu-v6_4-00902C ]; then

        echo "successfully entered if block!!"

fi

5
उद्धरण मत भूलना! यहाँ देखें, क्यों: mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.5D
polym

@polym हे धन्यवाद, लेकिन मैंने अभी न्यूनतम संस्करण दिया था जो काम कर रहा था;): डी।
शुरुआती जूल

4

एक और तरीका है उन्हें नकारना:

: ${PACKAGENAME:?'$PACKAGENAME variable is empty!'} #emits error and exits
[ -z "${PACKAGENAME#kakadu-v6_4-00902C}" ] || { #if var - str not empty do block
    echo '$PACKAGENAME is not kakadu-v6_4-00902C' 
    exit 1
} >&2

उपरोक्त ब्लॉक पहले परीक्षण करता है कि क्या "$PACKAGENAME"उसका कोई मूल्य है, और, यदि यह त्रुटि और गूँज के साथ बाहर नहीं निकलता ?'this'}है stderr। यदि इसका मूल शैल अभी भी मौजूद है, तो परीक्षण पास हो गया है, और यह अगले परीक्षण करता है यदि आपके 'काकाडू ...' स्ट्रिंग को -zखाली स्ट्रिंग में परिणाम देता है । यदि ऐसा नहीं होता है, तो यह फिर से एक त्रुटि का उत्सर्जन करता है और शेल को बाहर निकालता है। यदि आपका शेल ब्लॉक के निष्पादित होने के बाद भी इस बिंदु पर मौजूद है, अन्यथा यह नहीं है।

संभवतया इस प्रकार का कार्य किसी फ़ंक्शन में सबसे अच्छा कार्यान्वित किया जाता है। पसंद:

argeq() ( i= : ${2?^MERR: not enough parameters!} #$#>=2 || quit w/ err ^M == \r
    z() { return $((${#1}>0)) ; } #return 1 if ${#1}>0 else 0
    until z "${2+?}" $((i=i+1)) #until $2 is not set...
    do  ! z "$1" && z "${1#"$2"}" || #$1 != '' && $1 - $2 == '' or...
        exit $((i${1:++1})) #exit $? == failed arg count
    shift ; done #shift away one param ; continue loop
)

उस फ़ंक्शन के साथ आप उतने तर्क प्रदान कर सकते हैं जितना कि आपका सिस्टम अनुमति देगा। यदि आप 2 से कम प्रदान करते हैं तो यह 1 वापस आ जाएगा और संदेश को भेज दिया जाएगा stderr। यदि आप 2 या अधिक तर्क प्रदान करते हैं तो यह सभी को तार के रूप में मानेगा और 0 लौटाएगा यदि सभी समान हैं और शून्य नहीं हैं तो यह तर्क संख्या को लौटा देगा जो पहले चेक को विफल कर देता है।

आपके मामले में इसका उपयोग किया जा सकता है:

{   
    PACKAGENAME='kakadu-v6_4-00902C'
    argeq "$PACKAGENAME" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C == $PACKAGENAME" ||
        echo failure
    ! argeq "${PACKAGENAME#*-}" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C != ${PACKAGENAME#*-}" ||
        echo failure
}

###OUTPUT###
kakadu-v6_4-00902C == kakadu-v6_4-00902C
kakadu-v6_4-00902C != v6_4-00902C

आगे प्रदर्शित करने के लिए मैं एक और फ़ंक्शन लिखूंगा:

aeqecho() { i=$((i+1)) #inc for line#
    argeq "$@" && echo "$i : yay" || #allswell or
    ! e=$? ${2+:} return || #save $?; ! exclusive || to drop ERRs
    echo "$i : shite - arg$e failed" #report failure
}

डेमो:

{  i= s=string
   aeqecho $s #1
   aeqecho $s $s #2
   aeqecho "$s $s" #3
   aeqecho "$s $s" "${s} string" #4
   aeqecho "${s}1" $s string #5
   aeqecho "" "" "" #6
   aeqecho "" "$s" $s #7
   aeqecho 1 "${s#$s}1" $((2-1)) #8                     
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s stng #9  
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s string #10
}  

उत्पादन:

ERR: not enough parameters!
2 : yay
ERR: not enough parameters!
4 : yay
5 : shite - arg2 failed
6 : shite - arg1 failed
7 : shite - arg1 failed
8 : yay
9 : shite - arg13 failed
10 : yay
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.