&&
और ||
ऑपरेटरों रहे हैं नहीं करता है, तो-तो-और कुछ के लिए इनलाइन प्रतिस्थापन सटीक। हालाँकि अगर सावधानी से इस्तेमाल किया जाए, तो वे एक ही चीज़ को पूरा कर सकते हैं।
एक एकल परीक्षण सीधा और अस्पष्ट है ...
[[ A == A ]] && echo TRUE # TRUE
[[ A == B ]] && echo TRUE #
[[ A == A ]] || echo FALSE #
[[ A == B ]] || echo FALSE # FALSE
हालांकि, कई परीक्षणों को जोड़ने का प्रयास अप्रत्याशित परिणाम प्राप्त कर सकता है ...
[[ A == A ]] && echo TRUE || echo FALSE # TRUE (as expected)
[[ A == B ]] && echo TRUE || echo FALSE # FALSE (as expected)
[[ A == A ]] || echo FALSE && echo TRUE # TRUE (as expected)
[[ A == B ]] || echo FALSE && echo TRUE # FALSE TRUE (huh?)
FALSE और TRUE दोनों क्यों गूँजते हैं?
यहाँ क्या हो रहा है कि हमने महसूस नहीं किया है &&
और ||
ओवरलोडेड ऑपरेटर हैं जो [[ ]]
हमारे और हमारे (और सशर्त निष्पादन) सूची की तुलना में सशर्त परीक्षण कोष्ठक के अंदर अलग-अलग कार्य करते हैं।
बैश मैनपेज से (संपादित) ...
सूचियाँ
एक सूची एक या एक से अधिक पाइपलाइनों का अनुक्रम है जो ऑपरेटरों में से एक द्वारा अलग किया जाता है; और, &&, या ││, और वैकल्पिक रूप से, और; या में से एक द्वारा समाप्त किया जाता है। इन सूची संचालकों में, && और list की समान पूर्वता है, उसके बाद; और, जिसकी समान पूर्वता है।
एक या एक से अधिक newlines का एक क्रम एक सूची में अर्धविराम के बजाय आदेशों को सीमांकित करने के लिए प्रकट हो सकता है।
यदि नियंत्रण ऑपरेटर द्वारा एक कमांड को समाप्त किया जाता है और, शेल एक उपधारा में पृष्ठभूमि में कमांड को निष्पादित करता है। शेल कमांड के समाप्त होने की प्रतीक्षा नहीं करता है, और रिटर्न की स्थिति 0. है। कमांड एक द्वारा अलग किया गया है; क्रमिक रूप से निष्पादित किया जाता है; शेल प्रत्येक कमांड के बदले में समाप्त होने का इंतजार करता है। वापसी की स्थिति निष्पादित अंतिम कमांड की निकास स्थिति है।
AND और OR सूची क्रमशः && और, नियंत्रण ऑपरेटरों द्वारा अलग किए गए अधिक पाइपलाइनों में से एक के अनुक्रम हैं। और या OR सूचियों को बाएं समरूपता के साथ निष्पादित किया जाता है।
एक और सूची का रूप है ...
command1 && command2
Command2 निष्पादित किया जाता है यदि, और केवल अगर, कमांड 1 शून्य से बाहर निकलने की स्थिति देता है।
एक या सूची में रूप है ...
command1 ││ command2
कमांड 2 को निष्पादित किया जाता है अगर और केवल अगर कमांड 1 एक गैर-शून्य निकास स्थिति देता है।
AND और OR सूचियों की वापसी स्थिति सूची में निष्पादित अंतिम कमांड की निकास स्थिति है।
हमारे अंतिम उदाहरण पर लौटते हुए ...
[[ A == B ]] || echo FALSE && echo TRUE
[[ A == B ]] is false
|| Does NOT mean OR! It means...
'execute next command if last command return code(rc) was false'
echo FALSE The 'echo' command rc is always true
(i.e. it successfully echoed the word "FALSE")
&& Execute next command if last command rc was true
echo TRUE Since the 'echo FALSE' rc was true, then echo "TRUE"
ठीक है। अगर यह सही है, तो अगले से अंतिम उदाहरण कुछ भी क्यों गूँजता है?
[[ A == A ]] || echo FALSE && echo TRUE
[[ A == A ]] is true
|| execute next command if last command rc was false.
echo FALSE Since last rc was true, shouldn't it have stopped before this?
Nope. Instead, it skips the 'echo FALSE', does not even try to
execute it, and continues looking for a `&&` clause.
&& ... which it finds here
echo TRUE ... so, since `[[ A == A ]]` is true, then it echos "TRUE"
एक से अधिक &&
या ||
कमांड सूची में उपयोग करते समय तर्क त्रुटियों का जोखिम काफी अधिक है।
अनुशंसाएँ
एक &&
या ||
एक कमांड सूची में काम करता है के रूप में की उम्मीद है तो बहुत सुरक्षित है। यदि यह एक ऐसी स्थिति है जहाँ आपको किसी अन्य क्लॉज़ की आवश्यकता नहीं है, तो निम्नलिखित जैसे कुछ का पालन करने के लिए स्पष्ट हो सकता है (अंतिम 2 आदेशों को समूहित करने के लिए घुंघराले ब्रेस आवश्यक हैं) ...
[[ $1 == --help ]] && { echo "$HELP"; exit; }
एकाधिक &&
और ||
ऑपरेटर, जहां अंतिम को छोड़कर प्रत्येक कमांड एक परीक्षण है (यानी कोष्ठक के अंदर [[ ]]
), आमतौर पर भी सभी के रूप में सुरक्षित होते हैं, लेकिन अंतिम ऑपरेटर अपेक्षा के अनुरूप व्यवहार करता है। अंतिम ऑपरेटर अधिक then
या एक else
खंड की तरह काम करता है ।
&&
और||
शेल ऑपरेटरों के रूप मेंcmd1 && cmd2 || cmd3
एक ही पूर्वता है,&&
में((...))
और[[...]]
पूर्ववर्तीता है||
(((a || b && c))
है((a || (b && c)))
)। एक ही चला जाता है के लिए-a
/-o
मेंtest
/[
औरfind
और&
/|
मेंexpr
।