Wie erhöhe ich eine Variable in bash?

446

Ich habe versucht, eine numerische Variable mit var=$var+1 und var=($var+1) ohne Erfolg zu erhöhen. Die Variable ist eine Zahl, obwohl bash sie als String zu lesen scheint.

Bash Version 4.2.45 (1) -Release (x86_64-pc-linux-gnu) unter Ubuntu 13.10.

    
user221744 03.12.2013, 17:34

7 Antworten

707

Es gibt mehrere Möglichkeiten, eine Variable in bash zu inkrementieren, aber das, was Sie versucht haben, ist nicht korrekt.

Sie können zum Beispiel arithmetische Erweiterung verwenden:

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

Oder Sie können let :

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

Siehe auch: Pfandrecht .

    
Radu Rădeanu 03.12.2013, 17:39
94
var=$((var + 1))

Arithmetik in bash verwendet $((...)) Syntax.

    
Paul Tanzini 03.12.2013 17:38
60

Leistungsanalyse verschiedener Optionen

Danke an Radu Rădeanus Antwort , die die folgenden Möglichkeiten bietet, eine Variable in bash zu erhöhen:

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

Es gibt noch andere Möglichkeiten. Schauen Sie sich zum Beispiel die anderen Antworten zu dieser Frage an.

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

Wenn Sie so viele Optionen haben, führt dies zu diesen zwei Fragen:

  1. Gibt es einen Leistungsunterschied zwischen ihnen?
  2. Wenn ja, welche, welche ist die beste?

Inkrementeller Leistungstestcode:

#!/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

Ergebnisse:

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

Fazit:

Es scheint, dass bash am schnellsten i+=1 ausführt, wenn $i als ganze Zahl deklariert ist. let -Anweisungen scheinen besonders langsam zu sein, und expr ist bei weitem die langsamste, weil sie nicht eingebaut ist.

    
wjandrea 05.10.2017 07:02
14

Es gibt auch folgendes:

var='expr $var + 1'

Achten Sie sorgfältig auf die Leerzeichen und ist nicht

Obwohl Radus Antworten und die Kommentare erschöpfend und sehr hilfreich sind, sind sie Bash-spezifisch. Ich weiß, dass du speziell nach Bash gefragt hast, aber ich dachte mir, dass ich reinkommen würde, seit ich diese Frage gefunden habe, als ich das gleiche mit sh in busybox unter uCLinux machen wollte. Dieser Portable jenseits der Bash.

    
tphelican 31.07.2015 19:15
9

Wenn Sie $var als Integer deklarieren, funktioniert das, was Sie beim ersten Mal versucht haben:

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

Referenz: Arten von Variablen, Bash Guide für Anfänger

    
Radon Rosborough 23.08.2016 01:11
6

In allen Antworten fehlt eine Methode - bc

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

bc wird von POSIX Standard festgelegt, sollte also auf allen vorhanden sein Versionen von Ubuntu und POSIX-kompatiblen Systemen. Die <<< Umleitung könnte für die Portabilität in echo "$VAR" | bc geändert werden, aber da die Frage nach bash fragt, ist es in Ordnung, nur <<< zu verwenden.

    
Sergiy Kolodyazhnyy 06.12.2015 23:19
4

Der Rückgabecode 1 issue ist für alle Standardvarianten ( let , (()) usw.) vorhanden. Dies verursacht häufig Probleme, z. B. in Skripten, die set -o errexit verwenden. Hier ist, was ich verwende, um Fehlercode 1 von mathematischen Ausdrücken zu verhindern, die zu 0 ;

auswerten
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
    
Juve 23.02.2017 14:58

Tags und Links