Bash'ta bir değişken nasıl artırılır?

454

Sayısal bir değişkeni, hem var=$var+1 hem de var=($var+1) 'yi başarılı olmadan kullanarak artırmaya çalıştım. Değişken bir sayıdır, ancak bash onu bir ip gibi okur gibi görünür.

Ubuntu 13.10'daki Bash sürüm 4.2.45 (1) -sayı (x86_64-pc-linux-gnu).

    
sordu user221744 03.12.2013 17:34

7 cevap

719

Bash'ta bir değişkeni arttırmanın birden fazla yolu var, ama denediğin doğru değil.

Örneğin aritmetik genişletme 'yi kullanabilirsiniz:

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

Veya let adresini kullanabilirsiniz:

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

Ayrıca bkz: İşte .

    
verilen cevap Radu Rădeanu 03.12.2013 17:39
99
var=$((var + 1))

Bash'ta aritmetik $((...)) sözdizimini kullanır.

    
verilen cevap Paul Tanzini 03.12.2013 17:38
62

Çeşitli seçeneklerin Performans Analizi

Bash'ta bir değişkeni artırmanın aşağıdaki yollarını sağlayan Radu Rădeanu'nun cevabı sayesinde:

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

Başka yollar da var. Örneğin, bu sorudaki diğer cevaplara bakın.

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

Çok fazla seçeneğe sahip olmak bu iki soruya yol açar:

  1. Aralarında bir performans farkı var mı?
  2. Hangi durumda, hangisi daha iyi performans gösteriyor?

Artımlı performans testi kodu:

#!/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=100000
while ((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)'
done

for 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

Sonuçlar:

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

Sonuç:

Görünüşe göre i+=1 bir tamsayı olarak bildirildiğinde bash $i 'yi gerçekleştirmede en hızlıdır. let ifadeleri özellikle yavaştır ve expr , en alçaktır çünkü bir yerleşik değildir.

    
verilen cevap wjandrea 05.10.2017 07:02
14

Ayrıca şunlar da var:

var='expr $var + 1'

Mekanlara dikkat edin ve ayrıca ' değil

Radu'nun cevapları ve yorumları, kapsamlı ve çok yardımcı olsa da, bunlar bash'a özgüdür. Özellikle bash hakkında sorduğunu biliyorum, ama uCLinux altında meşgul kutusunda sh kullanarak aynı şeyi yapmak istediğimde bu soruyu bulduğumda boru döşemeyi düşündüm. Bu, bash'ın ötesinde taşınabilir.

    
verilen cevap tphelican 31.07.2015 19:15
9

$var değerini bir tamsayı olarak bildirirseniz, ilk kez denediğinizde aslında işe yarayacaktır:

$ declare -i var=5
$ echo $var
5
$ var=$var+1
$ echo $var
6

Referans: Değişken Türleri, Yeni Başlayanlar İçin Bash Rehberi

    
verilen cevap Radon Rosborough 23.08.2016 01:11
6

Tüm cevaplarda eksik bir yöntem var - bc

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

bc , POSIX standardıyla belirtilmiştir, bu nedenle hepsinde mevcut olmalıdır Ubuntu ve POSIX uyumlu sistemlerin sürümleri. % Co_de% yönlendirme, taşınabilirlik için <<< olarak değiştirilebildi, ancak soru echo "$VAR" | bc 'den sorulduğundan, bash ' yi kullanmanız yeterlidir.

    
verilen cevap Sergiy Kolodyazhnyy 06.12.2015 23:19
4

Tüm varsayılan değişkenler için 1 döndürme kodu mevcut ( let , (()) , vb.). Bu genellikle sıkıntı yaratır, ör.% Co_de% kullanan komut dosyalarında. İşte set -o errexit olarak değerlendirilen matematik ifadelerinden% co_de hata kodunu önlemek için kullanıyorum;

math() { (( "[email protected]" )) || true; }

math a = 10, b = 10
math a++, b+=2
math c = a + b
math mod = c % 20
echo $a $b $c $mod
#11 12 23 3
    
verilen cevap Juve 23.02.2017 14:58

Etiketlerdeki diğer soruları oku