बाश में सरल तार्किक ऑपरेटरों


256

मेरे पास कुछ चर हैं और मैं निम्नलिखित शर्त (शब्दों में लिखी गई, फिर बैश स्क्रिप्टिंग में मेरा विफल प्रयास) की जाँच करना चाहता हूँ:

if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then 

do something

done.

और मेरे असफल प्रयास में, मैं साथ आया:

if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) ); 
  then
    scale=0.05
  fi

जवाबों:


682

आपने जो लिखा है वह वास्तव में लगभग काम करता है (यह काम करेगा यदि सभी चर संख्याएं थीं), लेकिन यह बिल्कुल भी एक मुहावरेदार तरीका नहीं है।

  • (…)कोष्ठक एक उपधारा इंगित करता है । उनके अंदर जो है वह अन्य भाषाओं की तरह अभिव्यक्ति नहीं है। यह आदेशों की एक सूची है (बस कोष्ठकों के बाहर की तरह)। इन आदेशों को एक अलग उपप्रकार में निष्पादित किया जाता है, इसलिए कोष्ठक के अंदर किए गए किसी भी पुनर्निर्देशन, असाइनमेंट आदि का कोष्ठकों के बाहर कोई प्रभाव नहीं पड़ता है।
    • एक प्रमुख डॉलर चिह्न के साथ, $(…)एक कमांड प्रतिस्थापन है : कोष्ठक के अंदर एक कमांड है, और कमांड से आउटपुट कमांड लाइन के हिस्से के रूप में उपयोग किया जाता है (अतिरिक्त विस्तार के बाद जब तक प्रतिस्थापन डबल कोट्स के बीच नहीं होता है, लेकिन यह एक और कहानी है ) ।
  • { … }ब्रेसिज़ कोष्ठक की तरह होते हैं, जिसमें वे समूह आदेश देते हैं, लेकिन वे केवल समूहन को प्रभावित करते हैं, समूहन को नहीं। कार्यक्रम x=2; { x=4; }; echo $x4 प्रिंट करता है, जबकि x=2; (x=4); echo $xप्रिंट 2। (इसके अलावा ब्रेसिज़ के लिए चारों ओर रिक्त स्थान की आवश्यकता होती है और समापन से पहले अर्धविराम होता है, जबकि यह नहीं है। यह सिर्फ एक सिंटैक्स क्वर्क है।)
  • ((…))डबल कोष्ठक एक अंकगणितीय अनुदेश को घेरता है, जो पूर्णांक पर एक संगणना है, जो कि अन्य प्रोग्रामिंग भाषाओं से मिलता जुलता है। इस सिंटैक्स का उपयोग ज्यादातर असाइनमेंट और सशर्त में किया जाता है।
    • उसी सिंटैक्स का उपयोग अंकगणितीय अभिव्यक्तियों में किया जाता है $((…)), जो अभिव्यक्ति के पूर्णांक मान तक विस्तृत होता है।
  • [[ … ]]डबल कोष्ठक सशर्त अभिव्यक्तियों को घेरते हैं । सशर्त अभिव्यक्तियों को ज्यादातर संचालकों पर बनाया जाता -n $variableहै जैसे परीक्षण करना कि क्या एक चर खाली है और -e $fileयदि कोई फ़ाइल मौजूद है तो परीक्षण करना है। स्ट्रिंग समानता ऑपरेटर भी हैं: "$string1" == "$string2"(सावधान रहें कि दाहिने हाथ की ओर एक पैटर्न है, उदाहरण के लिए [[ $foo == a* ]]परीक्षण जब $fooशुरू होता है aजबकि [[ $foo == "a*" ]]परीक्षण $fooबिल्कुल सही है a*), और परिचित !, &&और ||ऑपरेटरों के साथ-साथ समूहन के लिए नकारात्मकता, संयोजन और अव्यवस्था। ध्यान दें कि आपको प्रत्येक ऑपरेटर (जैसे [[ "$x" == "$y" ]], नहीं [[ "$x"=="$y" ]]) के चारों ओर एक स्थान की आवश्यकता है , और एक स्थान या एक चरित्र जैसे ;कोष्ठक के अंदर और बाहर दोनों (जैसे [[ -n $foo ]], नहीं[[-n $foo]])।
  • [ … ]सिंगल ब्रैकेट अधिक quirks (लेकिन पुराने और अधिक पोर्टेबल) के साथ सशर्त अभिव्यक्तियों का एक वैकल्पिक रूप है। अब किसी के लिए मत लिखो; जब आप उन लिपियों को ढूंढना शुरू कर दें, जिनके बारे में उन्हें चिंता है।

यह अपने टेस्ट को बैश में लिखने का मुहावरेदार तरीका है:

if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then

यदि आपको अन्य गोले के लिए पोर्टेबिलिटी की आवश्यकता है, तो यह तरीका होगा (प्रत्येक व्यक्ति परीक्षण के चारों ओर अतिरिक्त कोटिंग और ब्रैकेट के अलग-अलग सेट पर ध्यान दें, और =ksh / bash / zsh ==संस्करण के बजाय पारंपरिक ऑपरेटर का उपयोग करें ):

if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then

31
महान पोस्ट, कोष्ठक सारांश केवल आदर्श है।
कोमोडोवेव

10
==एक चर (जो भी है =) से तुलना करने के लिए उपयोग करने के लिए बेहतर है (जो भी है )
विल शेपर्ड

1
ओह, मेरा मतलब एकल (गोल) कोष्ठक है, भ्रम की स्थिति के लिए खेद है। हालांकि लोग [[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]एक उप प्रक्रिया शुरू नहीं करते हैं, हालांकि पहली गोली बिंदु स्पष्ट रूप से कहता है: "अंदर क्या है [कोष्ठक] कई अन्य भाषाओं की तरह एक अभिव्यक्ति नहीं है " - लेकिन यह निश्चित रूप से यहाँ है! यह शायद अनुभवी बैश जादूगर के लिए स्पष्ट है, लेकिन मुझे भी नहीं, तुरंत। भ्रम पैदा हो सकता है क्योंकि एकल कोष्ठक एक बयान में इस्तेमाल किया जा सकता है if, बस डबल ब्रैकेट के अंदर के भावों में नहीं।
पीटर - मोनिका

2
@protagonist ==वास्तव में "अधिक मुहावरेदार" नहीं है =। उनका एक ही अर्थ है, लेकिन ==एक ksh संस्करण भी है जो बाश और zsh में उपलब्ध है, जबकि =पोर्टेबल है। उपयोग करने का वास्तव में कोई फायदा नहीं है ==, और यह सादे श में काम नहीं करता है।
गिल्स एसओ- बुराई को रोकें '

2
@WillSheppard तुलना और असाइनमेंट के बीच पहले से ही कई अन्य अंतर हैं: तुलना ब्रैकेट के अंदर है, असाइनमेंट नहीं है; तुलना ऑपरेटर के आसपास रिक्त स्थान है, असाइनमेंट नहीं करता है; असाइनमेंट में बाईं ओर एक वैरिएबल नाम है, तुलना केवल शायद ही कभी कुछ ऐसा है जो बाईं ओर एक वैरिएबल नाम की तरह दिखता है और आपको वैसे भी उद्धरण देना चाहिए। आप ==अंदर लिख सकते हैं [[ … ]], यदि आप चाहते हैं, लेकिन =इसमें भी काम करने का फायदा है [ … ], तो मैं सलाह देता हूं कि इसका उपयोग करने की आदत न ==डालें।
गिल्स एसओ- बुराई को रोकें '

34

बहुत करीब

if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]]; 
  then 
    scale=0.05
  fi

कार्य करना चाहिए।

इसे तोड़ना

[[ $varA -eq 1 ]] 

जहां एक पूर्णांक तुलना है

$varB == 't1'

एक स्ट्रिंग तुलना है। अन्यथा, मैं तुलनाओं को सही ढंग से समूहीकृत कर रहा हूं।

डबल वर्ग कोष्ठक एक सशर्त अभिव्यक्ति का परिसीमन करते हैं। और, मुझे लगता है कि इस विषय पर एक अच्छा पढ़ने के लिए निम्नलिखित हैं: "(आईबीएम) टेस्ट को डीमिस्टिफाई करें, [, [[, (और, और फिर-फिर-और"


बस यह सुनिश्चित करने के लिए: उद्धृत 't1'करना अनावश्यक है, है ना? क्योंकि डबल कोष्ठकों में अंकगणितीय निर्देशों के विपरीत, जहां t1एक चर होगा, t1डबल ब्रैकेट में सशर्त अभिव्यक्ति में सिर्फ शाब्दिक स्ट्रिंग है। यानी, [[ $varB == 't1' ]]जैसा है , ठीक वैसा ही [[ $varB == t1 ]]?
पीटर - मोनिका

6

एक बहुत ही पोर्टेबल संस्करण (यहां तक ​​कि बोर्ने शेल को विरासत में):

if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ]
then    do-something
fi

इसमें [शेल में केवल एक उपप्रकार को चलाने का अतिरिक्त गुण है (जो कि प्रक्रिया है )।

यदि वैरिएबल में संख्यात्मक मान हैं, जैसे प्रतिस्थापित =करें-eq

  • 3 -eq 03 सच है, लेकिन
  • 3 = 03गलत है। (स्ट्रिंग तुलना)

3

यहाँ if-then-अन्यथा विवरण के लघु संस्करण के लिए कोड दिया गया है:

( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"

निम्नलिखित पर ध्यान दें:

  1. ||और &&यदि अंदर स्थित है तो परिचालक (यानी गोल कोष्ठक के बीच) तार्किक ऑपरेंड (या /) हैं

  2. ||और &&बाहर संचालन अगर हालत का मतलब है / अन्यथा

व्यावहारिक रूप से कथन कहता है:

अगर (a = 1 या b = 2) तो "ठीक है" और "नोक"


कोष्ठक ( ... )एक उपधारा बनाता है। { ... }इसके बजाय ब्रेसिज़ का उपयोग करना चाहते हैं । किसी भी उपधारा में बनाया गया राज्य कॉलर में दिखाई नहीं देगा।
क्लिंट पच

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