noqqe » blog | sammelsurium | photos | projects | about

Des öfteren schlage ich mich in Bash-Scripting mit den Meldungen “unärer Operator” und ähnlichen Fehlern herum. Inkrement über i=$[$i+1] funktionieren unter entsprechenden Umständen nicht. In Bash mit Zahlen umzugehen ist garnicht so leicht, finde ich. Manchmal werden die Zahlen als Char statt Int interpretiert und manchmal darf man zu einer Variable mit Wert 0 keine Addition durchführen. Das kann natürlich an meinen mangelnden Fähigkeiten liegen, aber heute habe ich mich auf die Suche nach Lösungen zu diesem Thema gemacht.

# 1
let i+=1 # increment
let i-=1 # decrement
# 2
let i++ # increment
let i-- # decrement
# 3
i=$[$i+1] # increment
i=$[$i-1] # decrement
# 4
i=$((i+1)) # increment
i=$((i-1)) # decrement
# 5
((i++)) # increment
((i--)) # decrement
# 6
i=$(expr $i + 1) # increment
i=$(expr $i - 1) # decrement
# 7
: $[ n = $n + 1 ] # increment
: $[ n = $n - 1 ] # decrement

Das waren so die üblichen Varianten mit denen ich mir die letzten Monate geholfen habe. Mitunter wirklich unschöne Sachen. Auf http://tldp.org/LDP/abs/html/declareref.html bin ich dann allerdings auf eine sehr elegante Lösung gestossen. Via “declare” lässt sich eine Variable auf einem bestimmten Typ festnageln. “declare -i VAR” deklariert (haha) die Variable “VAR” nach Integer. So lässt sich quasi direkt damit rechnen. Anschliessend das Beispiel um im Bild zu bleiben:

# Declare Variante
declare -i i # -i = integer
i=$i+1 # increment
i=$i-1 # decrement

Das geht wiederrum auch mit mehreren Variablen, Zahlen und Rechenoperationen. Ein kleines einzeiliges Beispiel:

j=5 ; k=12 ; declare -i i ; i=$j*10+$k/2 ; echo $i

Natürlich gibt es auch noch andere lustige Modi die man seiner Variable aufs Auge drücken kann:

declare -r # readonly
declare -a # array
declare -x # export variable
declare -f # function

Alles in Allem sehr nett. Werde jetzt erstmal ein paar Skripte umbauen. Denke ich.

Comments (3)

Paradiesstaub on 2010-05-27T00:26:21
Danke für die nützliche Recherche. Mein Favorit war bisher ((i++)).

noqqe on 2010-05-27T00:39:44
:) wir wurde auch gezwitschert, dass deine Methode eine Integer-Variable erzwingt. Dann würde ich auch dahin umsatteln. Gerne wieder.

user unknown on 2010-05-27T15:19:10
Da finde ich doch [code]j=5 ; k=12 ; i=$((j*10+k/2)); echo $i [/code] kürzer und praktischer. Der Vollständigkeit halber würde ich noch [code] ((i+=1)); echo $i[/code] erwähnen, aber nur der Vollständigkeit halber. Für besonders große Zahlen [code] echo "6^6^6" | bc [/code] und Nachkommastellen empfiehlt sich dann bc, wie man hier sieht. [code] echo "scale=42;pi=4*a(1);pi" | bc -l [/code]