बैश में एक चर कैसे बढ़ाएं?

मैंने दोनों का उपयोग करके एक संख्यात्मक चर बढ़ाने की कोशिश की है var=$var+1 और var=($var+1) सफलता के बिना । चर एक संख्या है, हालांकि बैश इसे स्ट्रिंग के रूप में पढ़ रहा है ।

बैश संस्करण 4.2.45 (1)-रिलीज (एक्स 86_64-पीसी-लिनक्स-जीएनयू) उबंटू 13.10 पर ।

बैश में एक चर को बढ़ाने के एक से अधिक तरीके हैं, लेकिन आपने जो कोशिश की वह सही नहीं है ।

आप उदाहरण के लिए उपयोग कर सकते हैं अंकगणित विस्तार:

var=$((var+1))((var=var+1))((var+=1))((var++))

या आप उपयोग कर सकते हैं let:

let "var=var+1"let "var+=1"let "var++"

यह भी देखें: http://tldp.org/LDP/abs/html/dblparens.html.

var=$((var + 1))

बैश उपयोग में अंकगणित $((...)) सिंटैक्स।

1 से वेतन वृद्धि के लिए विभिन्न विकल्प, और प्रदर्शन विश्लेषण

के लिए धन्यवाद राडू Rădeanu के जवाब यह बैश में एक चर को बढ़ाने के लिए निम्नलिखित तरीके प्रदान करता है:

var=$((var+1))((var=var+1))((var+=1))((var++))let "var=var+1"let "var+=1" let "var++"

अन्य तरीके भी हैं । उदाहरण के लिए, इस प्रश्न पर अन्य उत्तरों को देखें ।

let var++var=$((var++))((++var)){    declare -i var    var=var+1    var+=1}{    i=0    i=$(expr $i + 1)}

इतने सारे विकल्प होने से ये दो प्रश्न होते हैं:

  1. क्या उनके बीच कोई प्रदर्शन अंतर है?
  2. यदि हां, तो कौन सा, जो सबसे अच्छा प्रदर्शन करता है?

वृद्धिशील प्रदर्शन परीक्षण कोड:

#!/bin/bash# To focus exclusively on the performance of each type of increment# statement, we should exclude bash performing while loops from the# performance measure. So, let's time individual scripts that# increment $i in their own unique way.# Declare i as an integer for tests 12 and 13.echo > t12 'declare -i i; i=i+1'echo > t13 'declare -i i; i+=1'# Set i for test 14.echo > t14 'i=0; i=$(expr $i + 1)'x=100000while ((x--)); do    echo >> t0 'i=$((i+1))'    echo >> t1 'i=$((i++))'    echo >> t2 '((i=i+1))'    echo >> t3 '((i+=1))'    echo >> t4 '((i++))'    echo >> t5 '((++i))'    echo >> t6 'let "i=i+1"'    echo >> t7 'let "i+=1"'    echo >> t8 'let "i++"'    echo >> t9 'let i=i+1'    echo >> t10 'let i+=1'    echo >> t11 'let i++'    echo >> t12 'i=i+1'    echo >> t13 'i+=1'    echo >> t14 'i=$(expr $i + 1)'donefor script in t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14; do    line1="$(head -1 "$script")"    printf "%-24s" "$line1"    { time bash "$script"; } |& grep user    # Since stderr is being piped to grep above, this will confirm    # there are no errors from running the command:    eval "$line1"    rm "$script"done

परिणाम:

i=$((i+1))              user    0m0.992si=$((i++))              user    0m0.964s((i=i+1))               user    0m0.760s((i+=1))                user    0m0.700s((i++))                 user    0m0.644s((++i))                 user    0m0.556slet "i=i+1"             user    0m1.116slet "i+=1"              user    0m1.100slet "i++"               user    0m1.008slet i=i+1               user    0m0.952slet i+=1                user    0m1.040slet i++                 user    0m0.820sdeclare -i i; i=i+1     user    0m0.528sdeclare -i i; i+=1      user    0m0.492si=0; i=$(expr $i + 1)   user    0m5.464s

निष्कर्ष:

ऐसा लगता है कि बैश प्रदर्शन करने में सबसे तेज है i+=1 जब $i एक पूर्णांक के रूप में घोषित किया गया है । let बयान विशेष रूप से धीमी गति से लगते हैं, और expr अब तक सबसे धीमा है क्योंकि यह बैश में निर्मित नहीं है ।

यह भी है:

var=`expr $var + 1`

रिक्त स्थान का ध्यान रखें और यह भी ` नहीं है '

जबकि राडू के उत्तर, और टिप्पणियां, संपूर्ण और बहुत उपयोगी हैं, वे बैश-विशिष्ट हैं । मुझे पता है कि आपने विशेष रूप से बैश के बारे में पूछा था, लेकिन मुझे लगा कि मैं इस सवाल को तब से पाइप करूंगा जब मैं यूक्लिनक्स के तहत बिजीबॉक्स में एसएच का उपयोग करके एक ही काम करना चाहता था । बैश से परे यह पोर्टेबल।

यदि आप घोषणा करते हैं $var एक पूर्णांक के रूप में, फिर आपने पहली बार जो कोशिश की वह वास्तव में काम करेगी:

$ declare -i var=5$ echo $var5$ var=$var+1$ echo $var6

संदर्भ: चर के प्रकार, शुरुआती के लिए बैश गाइड

सभी उत्तरों में एक विधि गायब है - bc

$ VAR=7    $ bc <<< "$VAR+2"9$ echo $VAR7$ VAR=$( bc <<< "$VAR+1" )$ echo $VAR8

bc द्वारा निर्दिष्ट किया गया है POSIX मानक, इसलिए उबंटू और पॉज़िक्स-अनुरूप प्रणालियों के सभी संस्करणों पर मौजूद होना चाहिए । द <<< पुनर्निर्देशन को बदला जा सकता है echo "$VAR" | bc पोर्टेबिलिटी के लिए, लेकिन चूंकि सवाल पूछता है bash - बस उपयोग करना ठीक है <<<.

रिटर्न कोड 1 समस्या सभी डिफ़ॉल्ट वेरिएंट के लिए मौजूद है (let, (()), आदि । ). यह अक्सर परेशानी का कारण बनता है, उदाहरण के लिए, स्क्रिप्ट में जो उपयोग करते हैं set -o errexit. त्रुटि कोड को रोकने के लिए मैं यहां क्या उपयोग कर रहा हूं 1 गणित के भावों से जो मूल्यांकन करते हैं 0;

math() { (( "$@" )) || true; }math a = 10, b = 10math a++, b+=2math c = a + bmath mod = c % 20echo $a $b $c $mod#11 12 23 3

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

$ var=0$ echo $var0$ var="$(python -c 'print('$var'+1)')"$ echo $var1

या

$ var="$(printf '%s\n' $var'+1' | bc)"$ echo $var1

गंभीरता से यहां अन्य बेहतर विकल्पों में से एक का उपयोग करें ।

यह सुरक्षित शर्त है

(( var = var + 1 ))

यदि परिणामी मान शून्य नहीं है, तो त्रुटि पर निकास सेट करना आपकी स्क्रिप्ट को रोक देगा

set -evar=0(( var++ ))echo You will never get here