ट्रैक
/
Bash
Bash
/
सिलेबस
/
अंकगणित
अं

अंकगणित में Bash

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

अंकगणित के बारे में

Bash अंकगणित कर सकता है, लेकिन सिर्फ पूर्णांकों के साथ। अगर आपको दशमलव संख्याओं का गणित करना है, तो आपको किसी बाहरी प्रोग्राम को कॉल करना पड़ेगा (जैसे awk या bc)।

अंकगणित के ऑपरेटर मैनुअल में (प्राथमिकता के क्रम में) दिए गए हैं: Shell Arithmetic।

इसके अलावा, Bash अंकगणित सिर्फ कुछ खास जगहों पर ही करता है (जिन्हें अंकगणित के "कॉन्टेक्स्ट" कहते हैं)।

अंकगणितीय एक्सपैंशन

अंकगणितीय एक्सपैंशन कमांड सबस्टिट्यूशन जैसा दिखता है, बस इसमें दोहरे ब्रैकेट होते हैं।

$(( expression ))

यह सिंटैक्स एक्सप्रेशन को हल करने के परिणाम में एक्सपैंड हो जाता है। आमतौर पर इसे किसी वेरिएबल में परिणाम सहेजने के लिए इस्तेमाल किया जाता है:

x=$(( 3 + 4 ))
Note

ब्रैकेट के अंदर कितने स्पेस डालने हैं, यह आप पर निर्भर है। यह स्टाइल और पठनीयता की बात है।

x=$(( 3 + 4 ))
y=$((5+6))

आपका मित्रवत लेखक स्पेस जोड़ना पसंद करता है, ताकि ब्रैकेट के अंदर अंकगणितीय एक्सप्रेशन ज़्यादा साफ नज़र आए।

अंकगणितीय कंडीशनल

अंकगणितीय कंडीशनल दोहरे ब्रैकेट के अंदर किया जाता है, बिना शुरू के $ के:

(( expression ))

यह परिणाम के रूप में एक्सपैंड नहीं होता। लेकिन यह एक एग्ज़िट स्टेटस बनाता है।

  • अगर एक्सप्रेशन का परिणाम गैर-शून्य है, तो एग्ज़िट स्टेटस 0 (सफलता) होता है।
  • अगर एक्सप्रेशन का परिणाम शून्य है, तो एग्ज़िट स्टेटस 1 (विफलता) होता है।
Note

(( के अंदर Bash सही/गलत का वही मतलब लेता है जो C भाषा लेती है: शून्य गलत है, गैर-शून्य सही। Bash एग्ज़िट स्टेटस को जिस तरह देखता है, यह उससे बिल्कुल उल्टा है!

यह सिंटैक्स आमतौर पर दो जगहों पर इस्तेमाल होता है:

  1. किसी if स्टेटमेंट या while लूप के COMMAND वाले हिस्से के रूप में।

    if (( x == y - 1 )); then ...
    while (( y > 0 )); do ...
    
  2. किसी वेरिएबल की वैल्यू बदलने के लिए अकेले कमांड के रूप में।

    (( x = x + 1 ))
    echo "new value for x is $x"
    
    Caution

    इस तरह अंकगणित का इस्तेमाल set -e के साथ करते समय सावधान रहिए। अगर एक्सप्रेशन को हल करने पर शून्य आता है, तो एग्ज़िट स्टेटस गैर-शून्य होगा और Bash बंद हो जाएगा।

    x=0
    (( x++ ))
    echo "you will see this"
    
    set -e
    x=0
    (( x++ ))
    echo "shell exits on the previous line; you won't see this"
    

    ++ ऑपरेटर पर विस्तृत चर्चा के लिए Postincrement vs Preincrement पर यह लेख देखिए।

अंकगणितीय कॉन्टेक्स्ट वाली अन्य जगहें

कुछ और जगहें भी हैं जो अंकगणितीय कॉन्टेक्स्ट हैं:

  • अंकगणितीय for लूप।

    for (( i = 0; i < 10; i++ )); do
        echo "$i"
    done
    
  • जिस ऐरे को संख्याओं से इंडेक्स किया जाता है, उसका इंडेक्स वाला हिस्सा।

    echo "The next element is ${array[x + 1]}"
    # ................................^^^^^
    

    ऐरे के बारे में और जानने के लिए ऐरे कॉन्सेप्ट दस्तावेज़ पढ़िए।

  • ${var:offset:length} एक्सपैंशन के ऑफसेट और लंबाई वाले हिस्से।

  • let बिल्ट-इन कमांड।

    • ध्यान दीजिए कि (( expression )) को let "expresson" से ज़्यादा पसंद किया जाता है। अंकगणितीय कंडीशनल की तुलना में let एक्सप्रेशन पर फाइलनेम एक्सपैंशन और वर्ड स्प्लिटिंग लागू होती है, और इसमें कोटिंग ज़रूरी है।
  • वेरिएबल असाइनमेंट, जब वेरिएबल में "इंटीजर एट्रिब्यूट" हो।

    # variable x does not have the integer attribute
    x="3 + 4"
    declare -p x      # => declare -- x="3 + 4"
    
    # variable y has the integer attribute
    declare -i y
    y="4 + 5"
    declare -p y      # => declare -i y="9"
    
    Note

    लेखक की राय है कि declare -i का इस्तेमाल सीमित है। इसका मुख्य फायदा यह है कि यह "सादा" अंकगणित करने देता है (अंकगणितीय एक्सप्रेशन सिंटैक्स के बिना)। इससे आपके कोड को पढ़ने वालों को भ्रम हो सकता है, क्योंकि अंकगणितीय एक्सप्रेशन ऐसी जगहों पर हल हो जाते हैं जहाँ उम्मीद नहीं होती।

अंकगणितीय एक्सप्रेशन में वेरिएबल का इस्तेमाल

अंकगणितीय कॉन्टेक्स्ट की एक बात यहाँ देखिए, जो पठनीयता बढ़ाती है।

height=10
width=20
area=$(( height * width ))

क्या आपने ध्यान दिया कि अंकगणितीय एक्सप्रेशन में वेरिएबल के आगे $ डॉलर चिह्न नहीं है? Bash आपको ऐसा करने देता है। इससे एक्सप्रेशन पढ़ना बहुत आसान हो जाता है।

मैनुअल कहता है,

किसी एक्सप्रेशन के अंदर शेल वेरिएबल को पैरामीटर एक्सपैंशन सिंटैक्स के बिना भी नाम से इस्तेमाल किया जा सकता है।

यह ऐरे के एलिमेंट के लिए भी काम करता है:

point1=(10 15)  # these are (x, y) coordinates
point2=(20 7)
distance_squared=$(( (point1[0] - point2[0])**2 + (point1[1] - point2[1])**2 ))

लेकिन बाकी पैरामीटर एक्सप्रेशन के लिए उनका खास सिंटैक्स इस्तेमाल करना पड़ता है। जैसे किसी स्ट्रिंग की लंबाई दोगुनी करना:

s="hello world"
len=$(( ${#s} * 2 ))

और पोज़िशनल पैरामीटर के लिए भी ऐसा ही करना पड़ता है। अगर पहले दो पोज़िशनल पैरामीटर चौड़ाई और ऊँचाई दर्शाते हैं:

area=$(( $1 * $2 ))
GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।