मैं शेल स्क्रिप्ट में बूलियन चर की घोषणा और उपयोग कैसे कर सकता हूं?


976

मैंने निम्नलिखित सिंटैक्स का उपयोग करके एक शेल स्क्रिप्ट में बूलियन चर घोषित करने की कोशिश की:

variable=$false

variable=$true

क्या ये सही है? इसके अलावा, अगर मुझे लगता है कि चर मैं एक ही वाक्यविन्यास का उपयोग करना चाहते हैं अद्यतन करना चाहते थे? अंत में, बूलियन चर का उपयोग करने के लिए निम्नलिखित सिंटैक्स अभिव्यक्ति सही है?

if [ $variable ]

if [ !$variable ]

73
सावधान! trueऔर falseनीचे के अधिकांश स्निपेट के संदर्भ में सिर्फ सादे तार हैं, कि bash built-ins!!! कृपया नीचे माइक होल्ट का उत्तर पढ़ें। (यह एक उदाहरण है जहां एक अत्यधिक मतदान और स्वीकार किए गए उत्तर IMHO भ्रमित करने वाला है और कम मतदान वाले उत्तरों में व्यावहारिक सामग्री छाया है)
mjv

7
@mjv इस सवाल (और मीकू के जवाब) पर अधिकांश भ्रम इस तथ्य के कारण था कि मिकू ने कुछ बिंदुओं पर पोस्ट किए जाने के बाद अपने जवाब को संशोधित किया, जिसमें बताया गया था कि कैसे मिकू के जवाब में बाश बिल्ट-इन कॉलिंग शामिल है true। मिकू के मूल उत्तर को वास्तव में trueबिल्ट-इन कहा जाता है, लेकिन संशोधित उत्तर नहीं मिला। इससे मिकू के कोड के काम करने के तरीके के बारे में गलत टिप्पणी प्रकट हुई। तब से मिकू का उत्तर मूल और संशोधित कोड दोनों को स्पष्ट रूप से दिखाने के लिए संपादित किया गया है। उम्मीद है कि यह एक बार और सभी के लिए आराम करने के लिए भ्रम पैदा करता है।
माइक होल

2
[ true ] && echo yes, true is trueऔर (अपरकेस) [ false ] && echo yes, false is also true। / बिन / सच और / बिन / झूठ एक रिटर्न कोड $ देता है? तुलना के लिए कार्यों के लिए नहीं।
fcm

अगर var सेट किया गया है variable=somethingतो यह सच है, अगर variable=वह unset जो झूठा [[ $variable ]] && echo true || echo falseऔर उल्टा होगा[[ ! $variable ]] && echo false || echo true
Ivan

जवाबों:


1200

संशोधित उत्तर (12 फरवरी, 2014)

the_world_is_flat=true
# ...do something interesting...
if [ "$the_world_is_flat" = true ] ; then
    echo 'Be careful not to fall off!'
fi

मूल उत्तर

कैविट्स: https://stackoverflow.com/a/21210966/89391

the_world_is_flat=true
# ...do something interesting...
if $the_world_is_flat ; then
    echo 'Be careful not to fall off!'
fi

से: बैश में बूलियन चर का उपयोग करना

मूल उत्तर को यहां शामिल किया गया है, क्योंकि 12 फरवरी 2014 को संशोधन से पहले की गई टिप्पणियां केवल मूल उत्तर से संबंधित हैं, और संशोधित उत्तर के साथ जुड़े होने पर कई टिप्पणियां गलत हैं। उदाहरण के लिए, डेनिस विलियमसन की बैन बिल्डिन के बारे में true2 जून 2010 की टिप्पणी केवल मूल उत्तर पर लागू होती है, संशोधित नहीं।


37
यह समझने के लिए कि क्या हो रहा है: ifकथन चर की सामग्री को निष्पादित कर रहा है जो बैश बिलिन है true। किसी भी कमांड को वेरिएबल की वैल्यू के रूप में सेट किया जा सकता है और इसके एग्जिट वैल्यू का मूल्यांकन किया जाएगा।
अगली सूचना तक रोक दिया गया।

7
@pms ऑपरेटर "-o" और "-a" केवल "परीक्षण" कमांड (उर्फ "[]") के लिए हैं। इसके बजाय, यह "इफ + कमांड" है, बिना "टेस्ट" के। (जैसे: अगर grep foo फ़ाइल; तब ... "।) इसलिए, सामान्य &&और ||ऑपरेटरों का उपयोग करें : # t1=true; t2=true; f1=false;# if $t1 || $f1; then echo is_true ; else echo is_false; fi; (रिटर्न" सत्य ", t1 = true के बाद से) # if $t1 && $f1 || $t2; then echo is_true ; else echo is_false; fi (रिटर्न" सत्य ", t2 = true के बाद से) । फिर, यह केवल इसलिए काम करता है क्योंकि "सही" / "गलत" बैश-बिल्डिन्स हैं (सही / गलत लौटाते हुए)। आप "if $ var ..." का उपयोग नहीं कर सकते हैं जब तक कि var एक cmd (यानी, सत्य या असत्य) नहीं है
माइकल

14
-1, स्पष्टीकरण के लिए मेरा जवाब देखें
डेनिस

3
गलत जानकारी के बहुत सारे, यहाँ। / बिन / सच प्रभावी ढंग से उपयोग नहीं किया जा रहा है। देखें डेनिस का जवाब।
akk

1
यह कोड समान नहीं है और लिंक किए गए लेख की तरह ही काम नहीं करता है। लिंक किए गए कोड एक प्रोग्राम को चर में संग्रहीत नाम से बुलाते हैं, लेकिन इस उत्तर में कोड केवल स्ट्रिंग तुलना है।
क्वोलोन प्रश्न

794

टी एल; डॉ

bool=true

if [ "$bool" = true ]

मिकू के ( मूल ) उत्तर वाले मुद्दे

मैं स्वीकृत उत्तर 1 की सिफारिश नहीं करता । इसका सिंटैक्स सुंदर है, लेकिन इसमें कुछ खामियां हैं।

कहें कि हमारी निम्नलिखित स्थिति है।

if $var; then
  echo 'Muahahaha!'
fi

निम्नलिखित मामलों में 2 , इस हालत के लिए मूल्यांकन करेंगे सच और एकत्रित आदेश पर अमल।

# Variable var not defined beforehand. Case 1
var=''  # Equivalent to var="".        Case 2
var=    #                              Case 3
unset var  #                           Case 4
var='<some valid command>'  #          Case 5

आमतौर पर आप केवल यह चाहते हैं कि आपकी स्थिति तब सही होती है जब आपका "बूलियन" वैरिएबल varइस उदाहरण में स्पष्ट रूप से सेट हो। अन्य सभी मामले खतरनाक रूप से भ्रामक हैं!

अंतिम मामला (# 5) विशेष रूप से शरारती है क्योंकि यह चर में निहित कमांड को निष्पादित करेगा (यही कारण है कि वैध 3, 4 के लिए सही स्थिति का मूल्यांकन करता है )।

यहाँ एक हानिरहित उदाहरण है:

var='echo this text will be displayed when the condition is evaluated'
if $var; then
  echo 'Muahahaha!'
fi

# Outputs:
# this text will be displayed when the condition is evaluated
# Muahahaha!

अपने चर का हवाला देते हुए सुरक्षित है, जैसे if "$var"; then। उपरोक्त मामलों में, आपको चेतावनी मिलनी चाहिए कि कमांड नहीं मिली है। लेकिन हम अभी भी बेहतर कर सकते हैं (तल पर मेरी सिफारिशें देखें)।

मिक होल्ट के मिकू के मूल उत्तर की व्याख्या भी देखें।

हबर के जवाब के साथ मुद्दे

इस दृष्टिकोण में अप्रत्याशित व्यवहार भी है।

var=false
if [ $var ]; then
  echo "This won't print, var is false!"
fi

# Outputs:
# This won't print, var is false!

आप उपरोक्त शर्त की अपेक्षा करेंगे कि झूठी का मूल्यांकन करें, इस प्रकार नेस्टेड कथन को कभी निष्पादित नहीं करेंगे। आश्चर्य!

मान ( "false") का हवाला देते हुए, चर को उद्धृत करते हुए ( "$var"), या का उपयोग करके testया [[इसके बजाय [, कोई फर्क नहीं पड़ता।

मैं क्या सलाह देता हूं :

यहां मैं आपके "बुलियन" की जांच करने के तरीके सुझाता हूं। वे उम्मीद के मुताबिक काम करते हैं।

bool=true

if [ "$bool" = true ]; then
if [ "$bool" = "true" ]; then

if [[ "$bool" = true ]]; then
if [[ "$bool" = "true" ]]; then
if [[ "$bool" == true ]]; then
if [[ "$bool" == "true" ]]; then

if test "$bool" = true; then
if test "$bool" = "true"; then

वे सभी बहुत ज्यादा समतुल्य हैं। आपको अन्य उत्तर 5 में दृष्टिकोण की तुलना में कुछ अधिक कीस्ट्रोक्स टाइप करना होगा , लेकिन आपका कोड अधिक रक्षात्मक होगा।


फुटनोट

  1. मिकू का उत्तर तब से संपादित किया गया है और अब उसमें (ज्ञात) खामियां नहीं हैं।
  2. एक संपूर्ण सूची नहीं।
  3. इस संदर्भ में एक मान्य कमांड का अर्थ है एक कमांड जो मौजूद है। इससे कोई फर्क नहीं पड़ता कि कमांड सही तरीके से या गलत तरीके से इस्तेमाल किया गया है। उदाहरण के man womanलिए, फिर भी एक वैध आदेश माना जाएगा, भले ही ऐसा कोई आदमी पृष्ठ मौजूद न हो।
  4. अमान्य (गैर-मौजूद) आदेशों के लिए, बैश बस शिकायत करेंगे कि कमांड नहीं मिला।
  5. यदि आप लंबाई के बारे में परवाह करते हैं, तो पहली सिफारिश सबसे छोटी है।

8
के ==साथ उपयोग करना [या testपोर्टेबल नहीं है। पोर्टेबिलिटी को ध्यान में रखते हुए एक ही फायदा है [/ testखत्म हो गया है [[, साथ रहना है =
चेपनर

2
@ सच कहूं तो मैं मछली को अपने प्राथमिक खोल के रूप में इस्तेमाल करता हूं, जिसमें मेरी राय में बैश की तुलना में एक सेंस स्क्रिप्टिंग भाषा है।
डेनिस

1
हाँ, मैं टिप्पणी में इस छिपे हुए मजाक के लिए कोई सराहना नहीं पा सका, इसलिए इसे इंगित करना पड़ा =)
क्रानच २०'१५

5
मेरे लिए, अवधारणात्मक रूप से यह समझना आसान है कि क्या मैं बूल = "सही" का उपयोग करता हूं। फिर यह स्पष्ट है कि यह सिर्फ एक तार है और कुछ विशेष मूल्य या बिलिन नहीं है।
वारबंकी

1
@ डॉल्मेन बिल्कुल, इनपुट का मूल्यांकन करना उतना जोखिम भरा नहीं है जब आप इनपुट को नियंत्रित करते हैं, लेकिन मैं अभी भी इसे एक बुरा अभ्यास मानता हूं, जिससे बचा जा सकता है अगर इसे आसानी से टाला जा सके। किसी ने जो केवल पूर्व शैली को कभी देखा और उपयोग किया है, वह शायद इसकी खामियों के बारे में नहीं जानता है जो अप्रत्याशित व्यवहार का कारण बन सकता है।
डेनिस

175

लगता है कि बैश बिलिन के बारे में कुछ गलतफहमी है true, और अधिक विशेष रूप से, के बारे में कि कैसे कोष्ठक के अंदर भाव का विस्तार और व्याख्या करता है।

मिकू के जवाब में कोड का बाश बिलिन के साथ कोई लेना-देना नहीं है true, न /bin/trueही और न ही trueकमांड का कोई अन्य स्वाद । इस मामले में, trueएक साधारण चरित्र स्ट्रिंग से अधिक कुछ भी नहीं है, और trueकमांड / बिल्डिन को कोई कॉल कभी नहीं किया जाता है, न तो चर असाइनमेंट द्वारा, और न ही सशर्त अभिव्यक्ति के मूल्यांकन के द्वारा।

निम्न कोड कार्यात्मक रूप से मिकू के उत्तर में कोड के समान है:

the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
    echo 'Be careful not to fall off!'
fi

यहाँ केवल अंतर यह है कि चार वर्णों की तुलना 'y', 'e', ​​'a' और 'h' के बजाय 't', 'r', 'u', और 'e' से की जाती है। बस। कमांड या बिलिन नाम से पुकारे जाने का कोई प्रयास नहीं किया गया है yeah, और न ही (मिकू के उदाहरण में) किसी भी प्रकार की विशेष हैंडलिंग तब चल रही है जब बैश टोकन को पार्स करता है true। यह सिर्फ एक स्ट्रिंग है, और उस पर पूरी तरह से मनमाना है।

अद्यतन (2014-02-19): मिकू के उत्तर में लिंक का अनुसरण करने के बाद, अब मैं देखता हूं कि कुछ भ्रम कहां से आ रहा है। मिकू का जवाब एकल कोष्ठक का उपयोग करता है, लेकिन कोड स्निपेट वह लिंक करता है जो कोष्ठक का उपयोग नहीं करता है। यह सिर्फ है:

the_world_is_flat=true
if $the_world_is_flat; then
  echo 'Be careful not to fall off!'
fi

दोनों कोड स्निपेट समान तरीके से व्यवहार करेंगे , लेकिन ब्रैकेट पूरी तरह से बदल जाते हैं जो हुड के नीचे चल रहा है।

यहाँ बाश प्रत्येक मामले में क्या कर रहा है:

कोई कोष्ठक नहीं:

  1. चर $the_world_is_flatको स्ट्रिंग में विस्तारित करें "true"
  2. "true"कमांड के रूप में स्ट्रिंग को पार्स करने का प्रयास ।
  3. trueकमांड को ढूंढें और चलाएं (या तो एक बेसिन या /bin/true, बैश संस्करण पर निर्भर करता है)।
  4. trueकमांड के निकास कोड की तुलना करें (जो हमेशा 0 होता है) 0. याद रखें कि अधिकांश गोले में, 0 का निकास कोड सफलता को इंगित करता है और कुछ भी विफलता का संकेत देता है।
  5. चूंकि एक्ज़िट कोड 0 (सफलता) था, ifस्टेटमेंट thenक्लॉज़ निष्पादित करें

कोष्ठक:

  1. चर $the_world_is_flatको स्ट्रिंग में विस्तारित करें "true"
  2. अब पूरी तरह से विस्तारित सशर्त अभिव्यक्ति को पार्स करें, जो फॉर्म का है string1 = string2=ऑपरेटर बैश की है स्ट्रिंग तुलना ऑपरेटर। इसलिए...
  3. एक स्ट्रिंग तुलना करें "true"और "true"
  4. हां, दो तार समान थे, इसलिए सशर्त का मूल्य सही है।
  5. ifकथन का thenखंड निष्पादित करें ।

नो-ब्रैकेट्स कोड काम करता है, क्योंकि trueकमांड 0 का एग्जिट कोड देता है, जो सफलता को इंगित करता है। ब्रैकेटेड कोड काम करता है, क्योंकि मान के दाईं ओर $the_world_is_flatस्ट्रिंग शाब्दिक के समान है ।true=

बस पॉइंट होम ड्राइव करने के लिए, कोड के निम्नलिखित दो स्निपेट पर विचार करें:

यह कोड (यदि रूट विशेषाधिकारों के साथ चलता है) आपके कंप्यूटर को रिबूट करेगा:

var=reboot
if $var; then
  echo 'Muahahaha! You are going down!'
fi

यह कोड केवल "अच्छा प्रयास" प्रिंट करता है। रिबूट कमांड को नहीं कहा जाता है।

var=reboot
if [ $var ]; then
  echo 'Nice try.'
fi

अद्यतन (2014-04-14) अंतर =और ==: AFAIK के बीच टिप्पणियों में प्रश्न का उत्तर देने के लिए , कोई अंतर नहीं है। ==ऑपरेटर के लिए एक बैश विशेष पर्याय है =, और जहाँ तक मैंने देखा है, वे सभी संदर्भों में बिल्कुल वैसा ही काम करते हैं।

हालांकि, ध्यान दें कि मैं विशेष रूप से के बारे में बात कर रहा हूँ =और ==या तो में इस्तेमाल किया स्ट्रिंग तुलना ऑपरेटरों [ ]या [[ ]]परीक्षण। मुझे लगता है कि सुझाव दे नहीं कर रहा हूँ =और ==परस्पर विनिमय कर रहे हर जगह बैश में।

उदाहरण के लिए, आप स्पष्ट रूप से चर असाइनमेंट नहीं कर सकते हैं ==, जैसे var=="foo"(तकनीकी रूप से आप ऐसा कर सकते हैं, लेकिन varइच्छा का मूल्य होगा "=foo", क्योंकि बैश एक ==ऑपरेटर नहीं देख रहा है, यह एक =(असाइनमेंट) ऑपरेटर देख रहा है , उसके बाद शाब्दिक मूल्य ="foo", जो बस बन जाता है "=foo")।

इसके अलावा, हालांकि =और ==विनिमेय हैं, आपको यह ध्यान रखना चाहिए कि उन परीक्षणों पर कैसे काम होता है यह इस बात पर निर्भर करता है कि आप इसे अंदर उपयोग कर रहे हैं [ ]या नहीं [[ ]], और यह भी कि ऑपरेंड उद्धृत हैं या नहीं। आप इसके बारे में अधिक उन्नत बैश स्क्रिप्टिंग गाइड में पढ़ सकते हैं : 7.3 अन्य तुलना ऑपरेटर (स्क्रॉल करें नीचे चर्चा =और ==)।


नो-ब्रैकेट के दृष्टिकोण से आपको साफ, स्पष्ट (imo) वन-लाइनर्स $the_world_is_flat && echo "you are in flatland!"
लिखने की सुविधा मिलती है

9
सच। हालाँकि, मैं या तो (या खिलाफ) दृष्टिकोण की वकालत नहीं कर रहा हूँ। मैं बस कुछ गलत सूचनाओं को दूर करना चाहता था जो यहां मतदान कर रहे हैं, ताकि बाद में इस विषय पर ठोकर खाने वाले लोग गलतफहमी का एक गुच्छा लेकर नहीं चलेंगे कि यह सब कैसे काम करता है।
माइक होल

1
भ्रम का कारण यह है कि मिकू का मूल उत्तर 4 साल तक रहा। trueमूल जवाब के बारे में बिलिन के सभी संदर्भ बनाए गए थे। (12 फरवरी, 2014 को संशोधित उत्तर मिकू द्वारा प्रस्तुत नहीं किया गया था।) मैंने मूल और संशोधित दोनों को शामिल करने के लिए उत्तर को संपादित किया है। तब लोगों की टिप्पणियों से समझ में आता है।
वारबैंक

1
यहां दिए गए उत्तरों को पढ़ने से, मुझे यह आभास होता है कि वास्तव में वास्तविक का उपयोग करने जैसी कोई चीज नहीं है true। क्या उधर रास्ता है? मुझे कई प्रोग्रामर्स पर शक है, जो bashअपनी ज़िंदगी को थोड़ा आसान बनाने के लिए कुछ गोंद को मिलाने में उनकी सहायता करने के लिए इस उत्तर को देखने के लिए सख्त भाषा का इस्तेमाल करते हैं, एक ===ऑपरेटर चाहते हैं ताकि स्ट्रिंग्स और "बुलियन" वास्तव में विनिमेय न हों। क्या उन्हें सिर्फ 0 और 1 से चिपके रहना चाहिए और क्वॉलोन प्रश्न के उत्तर(( $maybeIAmTrue )) में सुझाए अनुसार उपयोग करना चाहिए ?
सेलेडमनेडी

2
SeldomNeedy की टिप्पणी को संबोधित करने के लिए, हाँ, आप वास्तविक का उपयोग कर सकते हैं true, लेकिन आम तौर पर किसी चर के खिलाफ तुलना करने के लिए नहीं, क्योंकि वास्तविक trueका प्रति मूल्य नहीं है। यह सब कुछ 0सफलता की ओर इशारा करते हुए बाहर निकलने की स्थिति निर्धारित करता है । यह ध्यान देने योग्य है कि यह अनिवार्य रूप से तथाकथित "नल कमांड" के बराबर है, या :। जहाँ तक उपयोग करने 0और 1, यही मैं अपनी सभी लिपियों में इन दिनों करता हूँ जहाँ मुझे बूलियन्स की आवश्यकता होती है। और मैं मूल्यांकन के (( ))बजाय ऑपरेटर का उपयोग करता हूं [[ ]]। इसलिए, उदाहरण के लिए, अगर मेरे पास है flag=0, तो मैं कर सकता हूंif (( flag )); then ...
माइक होल

57

अंकगणित के भावों का प्रयोग करें।

#!/bin/bash

false=0
true=1

((false)) && echo false
((true)) && echo true
((!false)) && echo not false
((!true)) && echo not true

आउटपुट:

सच
झूठ नहीं


3
पेशेवरों: (1.) व्यवहार सी के तरीके से निपटने के बूल के समान है, (2.) वाक्यविन्यास बहुत संक्षिप्त / न्यूनतम है ('=' या '=='), (3) की तरह एक दाहिने हाथ चर और ऑपरेटरों की आवश्यकता नहीं है, (3) ।) <व्यक्तिपरक> मेरे लिए मैं समझता हूं कि एक लंबी घुमावदार व्याख्या के बिना क्या होता है ... मिकू और डेनिस के जवाबों के विपरीत जो दोनों को लंबे समय तक स्पष्टीकरण की आवश्यकता लगती है </ व्यक्तिपरक>
ट्रेवर बॉयड स्मिथ

3
@TrevorBoydSmith आपने सिर्फ यह क्यों नहीं कहा, "पेशेवरों: सब कुछ, विपक्ष: कुछ भी नहीं"। अपने कीबोर्ड पर मूल्यह्रास लागत को बचाएगा और लंबे समय में निगरानी करेगा।
क्वोलोन प्रश्न

4
एक-लाइनर्स की तरह इंटरैक्टिव उपयोग के लिए, बाद में एक स्थान छोड़ना सुनिश्चित करें !, या यह इतिहास का विस्तार करेगा। ((! foo))काम करता है, तो करता है ! ((foo))। मुझे यह समाधान पसंद है, बीटीडब्ल्यू। अंत में बूलियन चर करने का एक संक्षिप्त तरीका है। ((foo || bar))उम्मीद के मुताबिक काम करता है।
पीटर कॉर्ड्स

5
(())वैरिएबल को फिर से बढ़ाता है, जिसकी मुझे उम्मीद नहीं थी। foo=bar; bar=baz; ((foo)) && echo echoकुछ भी नहीं छापता है, लेकिन यह सच है baz=1। तो आप समर्थन foo=trueकरके और foo=falseसाथ ही 0 या 1 कर सकते हैं true=1
पीटर कॉर्ड्स

2
@quolonel बहुत उपयोगी संसाधन के लिए धन्यवाद। बेशक मेरी समझ सीमित है - यह मानव स्वभाव है कि सभी समझ में सीमित रहें चाहे डोमेन कोई भी हो। हालाँकि, क्या आप मुझे बताएंगे कि मेरे कौन से कथन से आप इस धारणा पर पहुँच सकते हैं कि इस विशेष मामले के बारे में मेरी समझ अधूरी है?
ह्यूबर्ट ग्रॉस्स्कोविआक

34

कहानी संक्षिप्त में:

बैश में बूलियन नहीं हैं

बैश की तुलना और स्थितियों के संदर्भ में बूलियन अभिव्यक्ति है। उस ने कहा, आप बैश में क्या घोषणा कर सकते हैं और तुलना कर सकते हैं। बस।

जहां भी आप देखते हैं trueया falseबैश में हैं, यह या तो एक स्ट्रिंग या एक कमांड / बिलिन है जो केवल इसके निकास कोड के लिए उपयोग किया जाता है।

यह वाक्य रचना ...

if true; then ...

अनिवार्य रूप से है ...

if COMMAND; then ...

यह शर्त सच है जब भी कमांड एग्जिट कोड 0. लौटाता है trueऔर falseबैश बिलियन होते हैं और कभी-कभी स्टैंडअलोन प्रोग्राम भी होते हैं जो संबंधित एग्जिट कोड को वापस करने के अलावा कुछ नहीं करते हैं।

उपरोक्त सशर्त इसके बराबर है:

COMMAND && ...

वर्ग कोष्ठक या testकमांड का उपयोग करते समय, आप उस निर्माण के निकास कोड पर भरोसा करते हैं। ध्यान रखें कि [ ]और [[ ]]भी किसी भी अन्य की तरह सिर्फ कमांड / बिल्डिंस हैं। इसलिए ...

if [[ 1 == 1 ]]; then echo yes; fi

से मेल खाती है

if COMMAND; then echo yes; fi

और COMMANDयहाँ है[[ 1 == 1 ]]

if..then..fiनिर्माण सिर्फ वाक्यात्मक चीनी है। आप हमेशा एक ही प्रभाव के लिए एक डबल एम्परसेंड द्वारा अलग किए गए कमांड चला सकते हैं:

[[ 1 == 1 ]] && echo yes

उपयोग करते समय trueऔर falseइन परीक्षण निर्माणों में आप वास्तव में केवल स्ट्रिंग "true"या "false"परीक्षण कमांड पास कर रहे हैं । यहाँ एक उदाहरण है:

मानो या न मानो लेकिन उन शर्तों को सभी एक ही परिणाम दे रहे हैं :

if [[ false ]]; then ...
if [[ "false" ]]; then ...
if [[ true ]]; then ...
if [[ "true" ]]; then ...

टी एल; डॉ; हमेशा स्ट्रिंग्स या संख्या के खिलाफ तुलना करें

भविष्य के पाठकों के लिए यह स्पष्ट करने के लिए, मैं हमेशा उद्धरणों का उपयोग करने की सलाह दूंगा trueऔर false:

करना

if [[ "${var}" == "true" ]]; then ...
if [[ "${var}" == "false" ]]; then ...
if [[ -n "${var:-}" ]]; then echo "var is not empty" ...

ऐसा नहीं

if [ ... ]; then ...  # Always use double square brackets in bash!
if [[ "${var}" ]]; then ...  # This is not as clear or searchable as -n
if [[ "${var}" != true ]]; then ...  # Creates impression of Booleans
if [[ "${var}" -eq "true" ]]; then ...  # `-eq` is for numbers and doesn't read as easy as `==`

शायद

if [[ "${var}" != "true" ]]; then ...  # Creates impression of Booleans. It can be used for strict checking of dangerous operations. This condition is false for anything but the literal string "true".

मैं उपयोग करना Tऔर Fस्पष्ट करना पसंद करता हूं कि वे वास्तविक बूलियन मूल्य नहीं हैं।
phk

1
मैं "हमेशा बैश में डबल ब्रैकेट्स का उपयोग करने" से सहमत नहीं हो सकता। वास्तव में लगभग सभी लिपियों में मैंने लिखा है कि मैं एकल ब्रैकेट का उपयोग कर रहा हूं, सिवाय इसके कि जब मुझे पैटर्न मिलान करने की आवश्यकता हो। मुझे लगता है कि किसी को [(यानी test) के बीच के अंतर को समझना चाहिए और [[उस का उपयोग करना चाहिए जो उसकी आवश्यकता के लिए उपयुक्त है।
वीजुन झोउ

@ WeijunZhou मन में जो मामलों में एकल कोष्ठक बेहतर हैं?
ह्यूबर्ट ग्रेज्सकोविआक

यह एक व्यक्तिगत स्वाद से अधिक है, मैं सिर्फ यह कहता हूं कि "हमेशा बैश में डबल स्क्वायर ब्रैकेट का उपयोग करें" कहना बहुत अधिक साहसिक है। लेकिन कुछ किनारे मामले हैं जिनका मैंने उपयोग किया है। एकल कोष्ठक आपको एक var में ही परीक्षण निर्दिष्ट करने की अनुमति देते हैं। एक बड़े उदाहरण के रूप में, विचार करेंif ....; then mytest='-gt'; else mytest='-eq'; fi; #several lines of code; if [ "$var1" "$mytest" "$var2" ]; then ...; fi
वीज़ुन झोउ

@ WeijunZhou आपका उदाहरण एकल वर्ग कोष्ठक के खिलाफ एक मजबूत तर्क है। यह कोड को समझने में अधिक कठिन बनाता है और त्रुटियों के लिए विंडो को व्यापक रूप से खोलता है। डबल ब्रैकेट अधिक सख्त होते हैं और क्लीनर कोड को प्रोत्साहित करते हैं।
ह्यूबर्ट ग्रौस्सोवाकियाक

18

बहुत पहले, जब हम सभी थे sh, बूलियन जहां testकार्यक्रम के एक सम्मेलन पर भरोसा करके संभाला जहांtest बिना किसी तर्क के चलने पर गलत निकास स्थिति देता है।

यह एक को एक चर के बारे में सोचने की अनुमति देता है जो कि किसी भी मूल्य के लिए गलत और परिवर्तनशील के रूप में सच नहीं है। आज, testबैश करने के लिए एक बिलियन है और आमतौर पर इसके एक-चरित्र उर्फ [(या गोले के रूप में इसका उपयोग करने के लिए एक निष्पादन योग्य, डोलमेन नोट्स के रूप में) द्वारा जाना जाता है :

FLAG="up or <set>"

if [ "$FLAG" ] ; then
    echo 'Is true'
else
    echo 'Is false'
fi

# Unset FLAG
#    also works
FLAG=

if [ "$FLAG" ] ; then
    echo 'Continues true'
else
    echo 'Turned false'
fi

सम्मेलनों को उद्धृत करने के कारण, स्क्रिप्ट लेखक उस यौगिक कमांड का उपयोग करना पसंद करते हैं [[जो नकल करता है test, लेकिन एक अच्छा वाक्यविन्यास है: रिक्त स्थान वाले चर को उद्धृत करने की आवश्यकता नहीं है; एक का उपयोग कर सकते हैं &&और ||अजीब पूर्वता साथ तार्किक ऑपरेटर के रूप में है, और वहाँ पदों की संख्या पर कोई POSIX सीमाएं हैं।

उदाहरण के लिए, यह निर्धारित करने के लिए कि FLAG सेट है और COUNT 1 से अधिक संख्या है:

FLAG="u p"
COUNT=3

if [[ $FLAG  && $COUNT -gt '1' ]] ; then
    echo 'Flag up, count bigger than 1'
else
    echo 'Nope'
fi

रिक्त स्थान, शून्य लंबाई के तार, और अशक्त चर की आवश्यकता होने पर यह सामान भ्रमित हो सकता है और यह भी कि आपकी स्क्रिप्ट को कई गोले के साथ काम करने की आवश्यकता होती है।


3
[अंदर सिर्फ एक उर्फ ​​नहीं है bash। यह उपनाम भी एक बाइनरी फ़ाइल के रूप में मौजूद है (या इंगित करने वाले लिंक के रूप में) और नंगे के साथ उपयोग किया जा सकता है sh। जाँच करें ls -l /usr/bin/\[। के साथ bash/ zshआपको इसके बजाय उपयोग करना चाहिए [[जो एक सच्चा शुद्ध आंतरिक है और बहुत अधिक शक्तिशाली है।
dolmen

1
@dolmen [और testबैश मैनुअल पेज के अनुसार बैश शेल बिल्डिन कमांड भी है, इसलिए प्रदर्शन में कोई समस्या नहीं होनी चाहिए। जैसे डैश के साथ एक ही बात। (/ बिन / श / सिर्फ़ / बिन / डैश का सहिष्णु हो सकता है)। निष्पादन योग्य का उपयोग करने के लिए आपको पूर्ण पथ का उपयोग करना होगा /usr/bin/\[
जारो

12

मैं शेल स्क्रिप्ट में बूलियन चर की घोषणा और उपयोग कैसे कर सकता हूं?

कई अन्य प्रोग्रामिंग भाषाओं के विपरीत, बैश इसके प्रकारों को "प्रकार" से अलग नहीं करता है। [1]

तो जवाब बहुत स्पष्ट है। बाश में कोई बूलियन चर नहीं है ।

तथापि:

डिक्लेयर स्टेटमेंट का उपयोग करके, हम वैरिएबल के लिए वैल्यू असाइनमेंट को सीमित कर सकते हैं। [2]

#!/bin/bash
declare -ir BOOL=(0 1) # Remember BOOL can't be unset till this shell terminates
readonly false=${BOOL[0]}
readonly true=${BOOL[1]}

# Same as declare -ir false=0 true=1
((true)) && echo "True"
((false)) && echo "False"
((!true)) && echo "Not True"
((!false)) && echo "Not false"

rमें विकल्प declareऔर readonlyराज्य के लिए प्रयोग किया जाता है स्पष्ट है कि चर हैं केवल पढ़ने के लिए । मुझे उम्मीद है कि उद्देश्य स्पष्ट है।


1
तुम बस क्यों नहीं करते declare -ir false=0 true=1? ऐरे का उपयोग करने से क्या फायदा है?
बेंजामिन डब्ल्यू।

@BenjaminW। मैं सिर्फ rविकल्प और readonlyकमांड के बारे में उल्लेख करना चाहता था । मैं इसे आपके लिपियों में सुझाए गए तरीके से करूंगा
sssam

शायद मैं कुछ याद किया, लेकिन इस तरह से डॉलर के चिह्न का उपयोग करने के लिए सही और गलत घोषित नहीं किया गया? $ सच $ झूठ
कोडीनिन्जा

सचमुच मेरे जवाब की नकल करके इसे और खराब कर दिया।
Quolonel प्रश्न

@QuolonelQuestions बैश ​​चर टाइप नहीं किए जाते हैं , इसलिए कहने का कोई मतलब नहीं है declare and use boolean variables। हम बस एक से अधिक तरीकों से नकल कर सकते हैं / मान सकते हैं कि एक चर का एक प्रकार है । मैंने आपके उत्तर में कहीं भी उल्लेख नहीं किया है।
sjsam

10

एक बूलियन को फैंकने और भविष्य के पाठकों के लिए एक जाल छोड़ने के बजाय, केवल सच्चे और झूठे से बेहतर मूल्य का उपयोग क्यों न करें?

उदाहरण के लिए:

build_state=success
if something-horrible; then
  build_state=failed
fi

if [[ "$build_state" == success ]]; then
  echo go home; you are done
else
  echo your head is on fire; run around in circles
fi

क्यों नहीं पूर्णांक?
दर्शन २

3
@Blauhirn क्योंकि पूर्णांकों का उपयोग भाषाओं के आधार पर अलग-अलग किया जाता है। कुछ भाषाओं में 0करने के लिए falseऔर 1करने के लिए coerces true। कार्यक्रम से बाहर निकलने के कोड के संबंध में (जो ऐतिहासिक रूप से उपयोग को कोसता है) यह 0सकारात्मक परिणाम के लिए है या trueबाकी सब कुछ नकारात्मक / त्रुटि या है false
ह्यूबर्ट ग्रेज्सकोविआक

7

POSIX (पोर्टेबल ऑपरेटिंग सिस्टम इंटरफ़ेस)

मुझे यहां महत्वपूर्ण बिंदु याद आता है, जो पोर्टेबिलिटी है। इसीलिए मेरे हेडर में अपने आप में POSIX है।

अनिवार्य रूप से, मतदान के सभी उत्तर सही हैं, अपवाद के साथ वे बैश- बहुत अधिक हैं।

मूल रूप से, मैं केवल पोर्टेबिलिटी के बारे में अधिक जानकारी जोड़ना चाहता हूं।


  1. [और ]जैसे कोष्ठक [ "$var" = true ]आवश्यक नहीं हैं, और आप उन्हें छोड़ सकते हैं और testसीधे कमांड का उपयोग कर सकते हैं :

    test "$var" = true && yourCodeIfTrue || yourCodeIfFalse

    महत्वपूर्ण नोट: मैं अब इसकी अनुशंसा नहीं करता क्योंकि यह धीरे-धीरे पदावनत हो रहा है और कई कथनों को संयोजित करने में अधिक कठिन है।

  2. कल्पना कीजिए कि उन शब्दों trueऔर falseखोल से क्या मतलब है, इसे स्वयं परखें:

    echo $(( true ))
    0
    echo $(( false ))
    1

    लेकिन उद्धरण का उपयोग कर:

    echo $(( "true" ))
    bash: "true": syntax error: operand expected (error token is ""true"")
    sh (dash): sh: 1: arithmetic expression: expecting primary: ""true""

    उसके लिए भी यही:

    echo $(( "false" ))

    शेल एक स्ट्रिंग के अलावा इसकी व्याख्या नहीं कर सकता है। मुझे उम्मीद है कि आप यह सोच रहे होंगे कि बिना उद्धरण के उचित खोजशब्द का उपयोग कितना अच्छा है ।

    लेकिन पिछले जवाबों में किसी ने नहीं कहा।

  3. इसका क्या मतलब है? खैर, कई बातें।

    • आपको बूलियन खोजशब्दों के लिए अभ्यस्त होना चाहिए वास्तव में संख्याओं की तरह व्यवहार किया जाता है, अर्थात true= 0और false= 1, याद रखें कि सभी गैर-शून्य मानों की तरह व्यवहार किया जाता है false

    • चूँकि उन्हें संख्याओं के रूप में माना जाता है, इसलिए आपको उनके साथ भी वैसा ही व्यवहार करना चाहिए, जैसे कि यदि आप चर को परिभाषित करते हैं:

      var_bool=true
      echo "$var_bool"
       true

      आप इसके साथ एक विपरीत मूल्य बना सकते हैं:

      var_bool=$(( 1 - $var_bool ))  # same as $(( ! $var_bool ))
      echo "$var_bool"
      1

    जैसा कि आप अपने लिए देख सकते हैं, शेल trueपहली बार आपके द्वारा उपयोग किए जाने वाले स्ट्रिंग को प्रिंट करता है, लेकिन तब से, यह क्रमशः संख्या का 0प्रतिनिधित्व trueया 1प्रतिनिधित्व करने के माध्यम से काम करता falseहै।


अंत में, आपको उस जानकारी के साथ क्या करना चाहिए

  • पहले, एक अच्छी आदत के 0बजाय काम करना होगा true; 1के बजाय false

  • दूसरी अच्छी आदत यह होगी कि यदि वेरिएबल शून्य के बराबर नहीं है, तो इसे टेस्ट करें:

    if [ "$var_bool" -eq 0 ]; then
         yourCodeIfTrue
    else
         yourCodeIfFalse
    fi

6

सिंटैक्स के बारे में, यह एक सरल पद्धति है जिसका उपयोग मैं (उदाहरण के लिए) बुलियन लॉजिक को लगातार और पूरी तरह से प्रबंधित करने के लिए करता हूं:

# Tests
var=
var=''
var=""
var=0
var=1
var="abc"
var=abc

if [[ -n "${var}" ]] ; then
    echo 'true'
fi
if [[ -z "${var}" ]] ; then
    echo 'false'
fi

# Results
# var=        # false
# var=''      # false
# var=""      # false
# var=0       # true
# var=1       # true
# var="abc"   # true
# var=abc     # true

यदि चर को कभी घोषित नहीं किया जाता है तो उत्तर है: # false

तो, एक चर को सही (इस सिंटैक्स पद्धति का उपयोग करके) सेट करने का एक सरल तरीका होगा var=1; इसके विपरीत var='',।

संदर्भ:

-n = सही है अगर var string की लंबाई non-zero है।

-z = सही है अगर var string की लंबाई शून्य है।


5

कई प्रोग्रामिंग भाषाओं में, बूलियन जैसे पूर्णांक, जहां की एक उप-प्रकार है, या के रूप में कार्यान्वित किया जाता है, trueकी तरह बर्ताव करती है 1और falseबर्ताव करता है जैसे 0:

गणितीय रूप से , बूलियन बीजगणित पूर्णांक अंकगणितीय मोडुलो से मिलता-जुलता है। इसलिए, यदि कोई भाषा मूल बूलियन प्रकार प्रदान नहीं करती है, तो पूर्णांकों का उपयोग करने के लिए सबसे प्राकृतिक और कुशल समाधान है। यह लगभग किसी भी भाषा के साथ काम करता है। उदाहरण के लिए, बैश में आप कर सकते हैं:

# val=1; ((val)) && echo "true" || echo "false"
true
# val=0; ((val)) && echo "true" || echo "false"
false

आदमी बैश :

((अभिव्यक्ति))

अभिव्यक्ति का मूल्यांकन ARITHMETIC EVALUATION के तहत नीचे वर्णित नियमों के अनुसार किया गया है। यदि अभिव्यक्ति का मूल्य गैर-शून्य है, तो वापसी की स्थिति 0 है; अन्यथा वापसी की स्थिति 1. यह "अभिव्यक्ति" को बताने के लिए बिल्कुल बराबर है।


5

बिल पार्कर को वोट दिया जा रहा है , क्योंकि उनकी परिभाषाएं सामान्य कोड सम्मेलन से उलट हैं। आम तौर पर, सच को 0 के रूप में परिभाषित किया जाता है और असत्य को नॉनज़ेरो के रूप में परिभाषित किया जाता है। 1 झूठा काम करेगा, जैसा कि 9999 और -1 होगा। फ़ंक्शन रिटर्न मानों के साथ भी यही है - 0 सफलता है और कुछ भी नॉनज़ेरो विफलता है। क्षमा करें, मेरे पास वोट देने या सीधे उसे जवाब देने के लिए अभी तक सड़क की विश्वसनीयता नहीं है।

बैश सिंगल ब्रैकेट्स के बजाय एक आदत के रूप में अब डबल ब्रैकेट्स का उपयोग करने की सलाह देते हैं, और माइक होल्ट ने जो लिंक दिया, वह इस बात का अंतर बताता है कि वे कैसे काम करते हैं। 7.3। अन्य तुलना संचालक

एक बात के लिए, -eqएक संख्यात्मक ऑपरेटर है, इसलिए कोड होना

#**** NOTE *** This gives error message *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

पूर्णांक अभिव्यक्ति की अपेक्षा करते हुए एक त्रुटि कथन जारी करेगा। यह या तो पैरामीटर पर लागू होता है, क्योंकि न तो पूर्णांक मान है। फिर भी, यदि हम इसके चारों ओर डबल ब्रैकेट लगाते हैं, तो यह एक त्रुटि स्टेटमेंट जारी नहीं करेगा, लेकिन यह एक गलत मान देगा (अच्छी तरह से, संभावित क्रमपरिवर्तन के 50% में)। यह [[0 -ईक सच]] = सफलता का मूल्यांकन करेगा, लेकिन [[0 -ईक झूठा]] = सफलता का भी, जो कि गलत है (हम्मम .... उस बिल्ट का संख्यात्मक मान क्या है?) के बारे में।

#**** NOTE *** This gives wrong output *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then

सशर्त के अन्य क्रमपरिवर्तन हैं जो गलत आउटपुट भी देंगे। मूल रूप से, कुछ भी (ऊपर सूचीबद्ध त्रुटि स्थिति के अलावा) जो एक चर को एक संख्यात्मक मान पर सेट करता है और इसकी तुलना एक सच्चे / झूठे बिलिन से करता है, या एक चर को एक सच्चे / झूठे बिलिन में सेट करता है और एक संख्यात्मक मान से तुलना करता है। इसके अलावा, कुछ भी जो एक चर को एक सच्चे / झूठे बिलिन में सेट करता है और एक तुलना का उपयोग करता है -eq। तो -eqबूलियन तुलना के लिए बचें और बूलियन तुलना के लिए संख्यात्मक मूल्यों का उपयोग करने से बचें। यहां उन अनुमतियों का सारांश दिया गया है जो अमान्य परिणाम देंगे:

# With variable set as an integer and evaluating to true/false
# *** This will issue error warning and not run: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then

# With variable set as an integer and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=0;
if [ "${The_world_is_flat}" -eq true ]; then
#
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" == true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then


# With variable set as an true/false builtin and evaluating to true/false
# *** These statements will not evaluate properly: *****
The_world_is_flat=true;
if [[ "${The_world_is_flat}" -eq true ]]; then
#
if [ "${The_world_is_flat}" = 0 ]; then
#
if [[ "${The_world_is_flat}" = 0 ]]; then
#
if [ "${The_world_is_flat}" == 0 ]; then
#
if [[ "${The_world_is_flat}" == 0 ]]; then

तो, अब क्या काम करता है। अपनी तुलना और अपने मूल्यांकन दोनों के लिए सच्चे / झूठे बिल्डरों का उपयोग करें (जैसा कि माइक हंट ने उल्लेख किया है, उन्हें उद्धरणों में संलग्न न करें)। फिर या तो सिंगल या डबल बराबर साइन (= या ==) और या तो सिंगल या डबल ब्रैकेट ([] या [[]]) का उपयोग करें। व्यक्तिगत रूप से, मुझे डबल बराबरी के संकेत पसंद हैं, क्योंकि यह मुझे अन्य प्रोग्रामिंग भाषाओं में तार्किक तुलना की याद दिलाता है, और केवल टाइपिंग की तरह दोहरे उद्धरण। तो ये काम:

# With variable set as an integer and evaluating to true/false
# *** These statements will work properly: *****
#
The_world_is_flat=true/false;
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" = true ]]; then
#
if [ "${The_world_is_flat}" = true ]; then
#
if [[ "${The_world_is_flat}" == true ]]; then

ये लो।


2
यहां अंतर्निहित true/ falseइंस का उपयोग नहीं किया गया है (कुछ संपादकों के वाक्यविन्यास हाइलाइटिंग को अनदेखा कर सकते हैं), विशेष रूप से उन […]मामलों में जिन्हें आप इसे एक साधारण स्ट्रिंग के रूप में सोच सकते हैं (एक जिसे [कमांड के पैरामीटर के रूप में दिया गया है )।
phk

अभी आपके पास है।
पीटर मोर्टेंसन

4

मेरे निष्कर्ष और सुझाव अन्य पदों से थोड़ा भिन्न हैं। मैंने पाया कि मैं "बूलियन" का उपयोग मूल रूप से किसी भी "नियमित" भाषा में कर सकता हूं, बिना "हूप जंपिंग" के सुझाव के ...

कोई भी []स्पष्ट स्ट्रिंग तुलना की आवश्यकता नहीं है ... मैंने कई लिनक्स वितरण की कोशिश की। मैंने बैश, डैश और बिजीबॉक्स का परीक्षण किया । परिणाम हमेशा समान थे। मुझे यकीन नहीं है कि मूल शीर्ष मतदान पोस्ट किस बारे में बात कर रहे हैं। शायद समय बदल गया है और यही सब कुछ है?

यदि आप एक चर सेट करते हैं true, तो यह बाद में एक सशर्त के भीतर "सकारात्मक" के रूप में मूल्यांकन करता है। इसे सेट करें false, और यह "नकारात्मक" का मूल्यांकन करता है। बहुत सीधा! एकमात्र चेतावनी, यह है कि अपरिभाषित चर भी सत्य की तरह मूल्यांकन करता है ! यह अच्छा होगा यदि यह विपरीत था (जैसा कि अधिकांश भाषाओं में होगा), लेकिन यह चाल है - आपको बस अपने बूलियंस को सही या गलत तरीके से स्पष्ट करने की आवश्यकता है

यह इस तरह से काम क्यों करता है? वह उत्तर दो गुना है। A) शेल में सही / गलत का अर्थ वास्तव में "कोई त्रुटि नहीं" बनाम "त्रुटि" है (अर्थात 0 बनाम कुछ और)। ख) सही / गलत मूल्य नहीं हैं - बल्कि शेल स्क्रिप्टिंग में कथन हैं ! दूसरे बिंदु के बारे में, निष्पादित trueया falseएक लाइन पर स्वयं द्वारा उस मान के लिए ब्लॉक का रिटर्न मान निर्धारित किया जाता है, अर्थात false"त्रुटि का सामना करना पड़ा" की घोषणा है, जहां सही "स्पष्ट" है। एक चर के साथ एक असाइनमेंट के साथ इसका उपयोग "रिटर्न" कि चर में। एक अपरिभाषित चर trueएक सशर्त में मूल्यांकन करता है क्योंकि यह समान रूप से 0 या "कोई त्रुटि का सामना नहीं करता" का प्रतिनिधित्व करता है।

उदाहरण बैश लाइनों और परिणाम नीचे देखें। यदि आप पुष्टि करना चाहते हैं तो इसे स्वयं परीक्षण करें ...

#!/bin/sh

# Not yet defined...
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=true
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

myBool=false
echo "when set to ${myBool}"
if ${myBool}; then echo "it evaluates to true"; else echo "it evaluates to false"; fi;

पैदावार

when set to
it evaluates to true
when set to true
it evaluates to true
when set to false
it evaluates to false


1

यहाँ एक संक्षिप्त हाथ का कार्यान्वयन है if true

# Function to test if a variable is set to "true"
_if () {
    [ "${1}" == "true" ] && return 0
    [ "${1}" == "True" ] && return 0
    [ "${1}" == "Yes" ] && return 0
    return 1
}

उदाहरण 1

my_boolean=true

_if ${my_boolean} && {
    echo "True Is True"
} || {
    echo "False Is False"
}

उदाहरण 2

my_boolean=false
! _if ${my_boolean} && echo "Not True is True"

हां, कार्यात्मक अपघटन की सराहना की जाती है।
पीटर मोर्टेंसन

1

मैंने मौजूदा जवाबों को भ्रामक पाया।

व्यक्तिगत रूप से, मैं बस कुछ ऐसा चाहता हूं जो सी की तरह दिखता है और काम करता है।

यह स्निपेट उत्पादन में दिन में कई बार काम करता है:

snapshotEvents=true

if ($snapshotEvents)
then
    # Do stuff if true
fi

और सभी को खुश रखने के लिए, मैंने परीक्षण किया:

snapshotEvents=false

if !($snapshotEvents)
then
    # Do stuff if false
fi

जिसमें ठीक काम भी हुआ।

$snapshotEventsचर के मूल्य की सामग्री का मूल्यांकन करता है। तो आपको जरूरत है $

आपको वास्तव में कोष्ठकों की आवश्यकता नहीं है, मैं सिर्फ उन्हें मददगार पाता हूं।


2
जहाँ आप कोष्ठक हटाते हैं, यह शीर्ष पर वास्तव में @ मिकू का मूल उत्तर है।
डोलमेन

1
कोष्ठक के बिना अभिव्यक्ति का मूल्यांकन नहीं होता है।
होगा

@ हाँ, यह करता है। आपको (।) की आवश्यकता नहीं है।
1729 पर phil294

1
@ बेलौहरन ... हाय, मैंने एक लिनक्स मिंट / उबंटू पीसी पर जीएनयू बैश के साथ प्रयोगों पर अपनी टिप्पणी आधारित की। आप सिद्धांत में शायद सही ()हैं -s की जरूरत नहीं है। मेरी केवल प्रतिक्रिया, इसे आज़माएं, यह बैश संस्करण, वास्तविक अभिव्यक्ति या संदर्भ और इस तरह पर निर्भर करता है।
होगा

1

यहाँ miku के मूल उत्तर पर एक सुधार है जो डेनिस विलियमसन के उस मामले के बारे में चिंताओं को संबोधित करता है जहाँ चर सेट नहीं होता है:

the_world_is_flat=true

if ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

और परीक्षण करने के लिए कि चर क्या है false:

if ! ${the_world_is_flat:-false} ; then
    echo "Be careful not to fall off!"
fi

चर में एक गंदा सामग्री के साथ अन्य मामलों के बारे में, यह एक प्रोग्राम में खिलाए गए किसी भी बाहरी इनपुट के साथ एक समस्या है।

इस पर भरोसा करने से पहले किसी भी बाहरी इनपुट को मान्य किया जाना चाहिए। लेकिन उस सत्यापन को केवल एक बार किया जाना चाहिए, जब वह इनपुट प्राप्त हो।

यह डेनिस विलियमसन की तरह परिवर्तन के हर उपयोग पर कार्यक्रम के प्रदर्शन को प्रभावित करने की जरूरत नहीं है ।


1

आप shFlags का उपयोग कर सकते हैं ।

यह आपको परिभाषित करने का विकल्प देता है: DEFINE_bool

उदाहरण:

DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");

कमांड लाइन से आप परिभाषित कर सकते हैं:

sh script.sh --bigmenu
sh script.sh --nobigmenu # False

GFlags इस जवाब में कोई मतलब नहीं है - यह एक C ++ पुस्तकालय है। इसे सीधे शेल स्क्रिप्ट में इस्तेमाल नहीं किया जा सकता है।
जोनाथन क्रॉस

ShFlags को अद्यतन प्रतिक्रिया जो शेल में GFlags का एक बंदरगाह है।
गोगस्का

0

यह बैश में "बुलियन" मूल्यों का परीक्षण करने के विभिन्न तरीकों के बारे में एक गति परीक्षण है:

#!/bin/bash
rounds=100000

b=true # For true; b=false for false
type -a true
time for i in $(seq $rounds); do command $b; done
time for i in $(seq $rounds); do $b; done
time for i in $(seq $rounds); do [ "$b" == true ]; done
time for i in $(seq $rounds); do test "$b" == true; done
time for i in $(seq $rounds); do [[ $b == true ]]; done

b=x; # Or any non-null string for true; b='' for false
time for i in $(seq $rounds); do [ "$b" ]; done
time for i in $(seq $rounds); do [[ $b ]]; done

b=1 # Or any non-zero integer for true; b=0 for false
time for i in $(seq $rounds); do ((b)); done

यह कुछ इस तरह प्रिंट होगा

true is a shell builtin
true is /bin/true

real    0m0,815s
user    0m0,767s
sys     0m0,029s

real    0m0,562s
user    0m0,509s
sys     0m0,022s

real    0m0,829s
user    0m0,782s
sys     0m0,008s

real    0m0,782s
user    0m0,730s
sys     0m0,015s

real    0m0,402s
user    0m0,391s
sys     0m0,006s

real    0m0,668s
user    0m0,633s
sys     0m0,008s

real    0m0,344s
user    0m0,311s
sys     0m0,016s

real    0m0,367s
user    0m0,347s
sys     0m0,017s

-2

वैकल्पिक - एक फ़ंक्शन का उपयोग करें

is_ok(){ :;}
is_ok(){ return 1;}
is_ok && echo "It's OK" || echo "Something's wrong"

फ़ंक्शन को परिभाषित करना कम सहज है, लेकिन इसकी वापसी मूल्य की जांच करना बहुत आसान है।


1
यह एक चर नहीं है जिसे आप परीक्षण कर सकते हैं, लेकिन एक निरंतर कार्य
जारो

@jarno किसी स्क्रिप्ट के प्रयोजनों के लिए किसी चर का परीक्षण करने से भिन्न फ़ंक्शन के रिटर्न मान का परीक्षण कर रहा है?
जोहानफ

खैर, सवाल चर के बारे में है।
जर्नो

यह सच है, हालांकि शेल स्क्रिप्ट में उपयोग समान होगा।
जोहानफ

-2

बैश वास्तव में की पसंद के साथ इस मुद्दे को confuses [, [[, ((, $((, आदि

सभी एक दूसरे के कोड स्पेस पर चलते हैं। मुझे लगता है कि यह ज्यादातर ऐतिहासिक है, जहां बैश को shकभी-कभार होने का नाटक करना पड़ता था ।

ज्यादातर समय, मैं बस एक विधि चुन सकता हूं और इसके साथ रह सकता हूं। इस उदाहरण में, मैं घोषित करता हूं (अधिमानतः एक सामान्य पुस्तकालय फ़ाइल में मैं .अपनी वास्तविक स्क्रिप्ट (ओं) के साथ शामिल कर सकता हूं)।

TRUE=1; FALSE=0

मैं तब उपयोग कर सकता हूँ ((... इस प्रकार ))परीक्षण करने के लिए अंकगणितीय ऑपरेटर।

testvar=$FALSE

if [[ -d ${does_directory_exist} ]]
then
    testvar=$TRUE;
fi

if (( testvar == TRUE )); then
    # Do stuff because the directory does exist
fi
  1. आपको अनुशासित होना पड़ेगा। आपका testvarचाहिए या तो के लिए सेट किया $TRUEया $FALSEहर समय।

  2. में ((... ))तुलनित्र, आपको पूर्ववर्ती की आवश्यकता नहीं है $, जो इसे अधिक पठनीय बनाता है।

  3. मैं ((... ))क्योंकि $TRUE=1और $FALSE=0संख्यात्मक मान का उपयोग कर सकता हूं ।

  4. नकारात्मक पक्ष को $कभी-कभार उपयोग करना पड़ता है:

    testvar=$TRUE

    जो इतना सुंदर नहीं है।

यह एक सही समाधान नहीं है, लेकिन यह हर मामले को कवर करता है जो मुझे इस तरह के परीक्षण की आवश्यकता है।


2
आपको अपने स्थिरांक को आसानी से घोषित करना चाहिए। कृपया चर का उपयोग करते समय हमेशा घुंघराले कोष्ठक का उपयोग करें। यह एक सम्मलेन है जिसे हर किसी को IMHO से चिपकना चाहिए। इस समाधान का बड़ा पहलू यह है कि आप बीजगणितीय अभिव्यक्ति को परीक्षण झंडे या स्ट्रिंग तुलना के साथ नहीं मिला सकते हैं।
ह्यूबर्ट ग्रेज्सकोविआक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.