शर

शर्तें में Bash

{one: "1 अभ्यास", other: "%{count} अभ्यास"}

शर्तें के बारे में

Bash में ट्रुथीनेस

Bash में बूलियन वैल्यू नाम की कोई चीज़ नहीं होती। यहाँ स्ट्रिंग और संख्याएँ होती हैं, और स्ट्रिंग या संख्याओं के ऐरे भी। तो फिर शर्त वाले कमांड सही और गलत को कैसे संभालते हैं?

एग्जिट स्टेटस

कमांड खत्म होते समय एक एग्जिट स्टेटस देते हैं। एग्जिट स्टेटस 0 से 255 तक, दोनों समेत, का एक पूर्णांक होता है। Bash में शून्य एग्जिट स्टेटस को सफलता माना जाता है। बाकी कोई भी एग्जिट स्टेटस विफलता दर्शाता है।

यह सभी कमांडों पर लागू होता है, जिनमें bash के बिल्ट-इन कमांड, कीवर्ड और फंक्शन भी शामिल हैं।

"if" कमांड

if कमांड का बुनियादी सिंटैक्स यह है

if CONDITIONAL_COMMANDS; then TRUE_COMMANDS; else FALSE_COMMANDS; fi

इसकी शुरुआत if से होती है; शर्त वाले कमांड और "सफलता" वाले कमांड को then अलग करता है; और इसका अंत fi से होता है। else लिखना ज़रूरी नहीं है।

CONDITIONAL_COMMANDS एक अकेला कमांड हो सकता है, या कमांडों की सूची हो सकती है।

CONDITIONAL_COMMANDS चलाए जाते हैं, और

  • अगर एग्जिट स्टेटस शून्य (सफलता) है, तो TRUE_COMMANDS चलाए जाते हैं।
  • अगर एग्जिट स्टेटस शून्य नहीं (विफलता) है, तो FALSE_COMMANDS चलाए जाते हैं, अगर वे दिए गए हों।

elif की मदद से एक के बाद एक कई शर्तें जोड़ी जा सकती हैं

if CONDITIONAL_COMMANDS
then TRUE_COMMANDS
elif CONDITIONAL_COMMANDS_2
then TRUE_COMMANDS_2
# more elif branches ...
else FALSE_COMMANDS
fi

then, elif, else और fi शब्दों से पहले एक सेमीकोलन या एक नई लाइन होनी चाहिए।

इसे ज़ोर देकर कहें: शर्त वाले कमांडों का एग्जिट स्टेटस ही फ्लो को कंट्रोल करता है। उदाहरण के लिए, grep तब 0 लौटाता है जब मैच मिल जाता है, और तब 1 जब मैच नहीं मिलता। -q ऑप्शन आउटपुट दबा देता है और सिर्फ एग्जिट स्टेटस देता है।

if grep -q "my pattern" my_file; then echo "the pattern is found in the file"; fi

"[" और "test" कमांड

CONDITIONAL_COMMANDS के आसपास कोई खास सिंटैक्स नहीं होता। आपने ऐसे if स्टेटमेंट देखे होंगे:

if [ "$password" = "secure" ]; then
    echo "Welcome!"
fi

[ कोई खास सिंटैक्स नहीं है। यह एक कमांड है जो शर्त वाले एक्सप्रेशन का मूल्यांकन करता है और सफलता/विफलता के स्टेटस के साथ खत्म होता है। सभी कमांडों की तरह, इसके और इसके आर्गुमेंट के बीच खाली जगह ज़रूरी है।

[ वास्तव में test कमांड का ही दूसरा रूप है। दोनों बिल्कुल एक जैसे हैं, बस फर्क इतना है कि [ का अंतिम आर्गुमेंट ] ही होना चाहिए।

शर्त वाले एक्सप्रेशन

[ और ] के अंदर आप एक शर्त वाला एक्सप्रेशन लिखते हैं। कुछ आम शर्त वाले एक्सप्रेशन ये हैं:

[ -f "$filename" ]             # file operations
[ "$string1" = "$string2" ]    # string comparisons
[ "$num1" -eq "$num2" ]        # arithmetic comparisons

और भी कई ऑपरेशन उपलब्ध हैं; इनकी सूची मैनुअल के Bash Conditional Expressions हिस्से में दी गई है।

Note

ऊपर के उदाहरणों में ध्यान दीजिए कि सभी वेरिएबल कोट किए गए हैं। test और [ साधारण कमांड हैं, जिनमें आर्गुमेंट बाकी कमांडों की तरह वर्ड स्प्लिटिंग और फाइलनेम एक्सपैंशन के अधीन होते हैं।

यह बताना ज़रूरी है क्योंकि शर्त वाले एक्सप्रेशन इस आधार पर अलग-अलग तरीके से मूल्यांकित होते हैं कि आप कितने आर्गुमेंट देते हैं:

  • 0 आर्गुमेंट: एग्जिट स्टेटस शून्य नहीं (विफलता) होता है
  • 1 आर्गुमेंट: अगर आर्गुमेंट खाली नहीं है तो एग्जिट स्टेटस शून्य (सफलता) होता है, और अगर खाली है तो शून्य नहीं।
  • 2 आर्गुमेंट: पहला आर्गुमेंट एक यूनरी ऑपरेटर होना चाहिए (जैसे [ -z "$name" ]), या एक ! (जो 1-आर्गुमेंट वाले टेस्ट के स्टेटस को उलट देता है)
  • और भी कई।

अगर आप कोट करना भूल जाएँ तो नतीजे अनपेक्षित हो सकते हैं:

str=""

# this prints "empty"
if [ -n "$str" ]; then echo "not empty"; else echo "empty"; fi

# leaving the variable unquoted results in incorrect "not empty" output
if [ -n $str ]; then echo "not empty"; else echo "empty"; fi

"[[" कीवर्ड

[[...]] शर्त वाली संरचना कोई कमांड नहीं है, यह एक कीवर्ड है। इसका मतलब है कि हालाँकि इसे बाकी कमांडों की तरह ही संभाला जाता है, इसके पार्सिंग के नियम खास होते हैं। [[ की खास बात यह है कि इसके अंदर एक्सपैंड होने वाले वेरिएबल वर्ड स्प्लिटिंग या फाइलनेम एक्सपैंशन के अधीन नहीं होते। यानी यह कमांड बिना कोट किए भी वैसा ही काम करता है जैसी आप उम्मीद करते हैं।

if [[ -n $str ]]; then echo "not empty"; else echo "empty"; fi

[[ उन सभी शर्त वाले एक्सप्रेशन को सपोर्ट करता है जिन्हें test और [ संभाल सकते हैं। इसके अलावा, [[ ये भी देता है

  • =~ रेगुलर-एक्सप्रेशन मैचिंग ऑपरेटर,
  • == और != ग्लॉब-पैटर्न मैचिंग ऑपरेटर की तरह काम करते हैं,
  • && और || लॉजिकल ऑपरेटर की तरह (पार्सिंग का खास नियम),
  • < और > "बिना कोट" स्ट्रिंग तुलना ऑपरेटर की तरह (पार्सिंग का खास नियम: चूँकि ये रीडायरेक्शन सिंबल हैं, [ में इन्हें एस्केप करना पड़ता है)।

आम तौर पर माना जाता है कि ये खास सुविधाएँ इतनी फायदेमंद हैं कि [[ का ही इस्तेमाल करना चाहिए। (उदाहरण के लिए, Google Shell Style Guide देखिए।)

"case" कमांड

case एक और कंट्रोल फ्लो कमांड है। यह दूसरी भाषाओं के "switch" स्टेटमेंट जैसा है।

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac

WORD को हर PATTERN से मिलाया जाता है। जब कोई एक मैच हो जाता है, तो COMMANDS चलाए जाते हैं।

read -p "Guess the secret word: " word
case "$word" in
    secret) echo "Yes, you guessed it!" ;;
    ??????) echo "That's the right number of letters." ;;
    s*)     echo "You guessed the first letter." ;;
    *)      echo "Not even close! Try again." ;;
esac

हर COMMANDS का अंत दो सेमीकोलन ;; से होना चाहिए।

Note
  1. कुछ और तरीके भी हैं जो फॉल-थ्रू कमांड एक्ज़ीक्यूशन और पैटर्न मैचिंग को जारी रखने की सुविधा देते हैं। जानकारी के लिए मैनुअल देखिए।
  2. याद कीजिए, हमने पैटर्न के बारे में कोटिंग कॉन्सेप्ट के Filename Expansion हिस्से में बात की थी।
GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।