Innerhalb des Operators $((
... ))
wird ein arithmetischer Ausdruck
ausgewertet. Dieser wird mit langen
Ganzzahlen (vier Byte) vorzeichenbehaftet berechnet; Ergebnis ist ein String, der die
berechnete Zahl repräsentiert. Die Operanden können Konstanten (in
oktaler Schreibweise, wenn sie mit der Ziffer 0 beginnen, in
hexadezimaler Schreibweise, wenn sie mit 0x oder 0X
beginnen, sonst dezimal) sein
oder die üblichen Variablen (Variablen, Parameter).
Eine Schachtelung solcher arithmetischen Ausdrücke ist möglich.
Als wahr und falsch gilt wie in C und ebenso wie in eval-Ausdrücken (Numerik light mit expr) ,,0 ist false, alles andere true``, also entgegengesetzt der in der Shell sonst verwendeten Faustformel, daß ein Kommando wahr beziehungsweise erfolgreich mit dem Wert 0 signalisiert (test-Ausdrücke, true, false).
i=4; j=5; j=$(( $((k = 2*i+j)) -2 ))
setzt i
auf den Wert 4, j auf anfangs 5, dann k auf
13 und letztlich nochmals j auf 11.
Man muß also die Variablen nicht explizit durch ein vorangestelltes
$
-Zeichen expandieren, dürfte es aber: $((k = 2*i+j))
kommt auf
das selbe Ergebnis wie $((k = 2*$i+$j))
; in letzterem Fall
würden die Variablen in einem früheren Schritt durch ihren Wert
ersetzt werden und die Berechnung erfolgt dann letztlich mit
Konstanten (dem Ergebnis der Expansion).
Bei einer Zuweisung an eine Variable (oder beim Inkrementieren mit
++
oder Dekrementieren mit --
) darf allerdings vor den
Variablen kein $
stehen, weil die Veränderung der expandierten Konstanten nicht möglich
ist.
Neben dem Operator $(( ))
gibt es noch die let-Anweisung, der man einen oder mehrere zu
berechnende Ausdrücke als Argumente übergibt. Dabei muß man allerdings
die Ausdrücke meistens durch quoten vor einer zu frühen
Auswertung durch die Shell schützen, beispielsweise
let "k = 3 + 6"
Derselbe Ausdruck ohne Gänsefüßchen würde nicht funktionieren, weil
vor dem Ausführen von let die Shell bereits das
Gleichheitszeichen entdeckt und dadurch eine direkte Zuweisung
versucht, ohne den arithmetischen Ausdruck auszuwerten. (Ohne
Leerzeichen, also let "k=3+6"
, würde es zufällig klappen, weil
das Gleichheitszeichen für die Shell in einem Wort versteckt ist.)
Folgende Operatoren stehen zur Verfügung:
++
, --
: Inkrement- und Dekrementoperatoren in Prä- und Postfixnotation
wie in C erhöhen beziehungsweise erniedrigen den Wert einer Variablen.
Steht der Operator vor dem Operanden (Präfixnotation, also ++
Variable
oder --
Variable), dann wird die Variable erst um
1 erhöht oder erniedrigt; der geänderte Wert wird gegebenenfalls
für den umgebenden Ausdruck verwendet.
Folglich gibt i=4; j=$(( ++i )); echo i=$i j=$j
aus:
i=5 j=5
weil i erst erhöht wird, und dann der manipulierte Wert an
j zugewiesen.
In der Postfixnotation dagegen wird die Variable zwar ebenfalls erhöht oder erniedrigt, aber im umgebenden Ausdruck wird noch der alte Wert verwendet.
In der Anweisung i=4; j=$(( i++ )); echo i=$i j=$j
wird
ausgegeben:
i=5 j=4
i wurde also von 4 auf 5 erhöht; an j wurde
aber noch der alte Wert zugewiesen.
+
und -
als unäre Operatoren (also mit nur einem
nachfolgenden Operanden) dienen wie üblich als Vorzeichen.
!
ist die logische Verneinung (also ein Test auf gleich
0), ~
ist die bitweise Negation
**
ist eine Exponentiation
*
dient zum Multiplizieren, /
zum Dividieren und
%
berechnet den Divisionsrest (modulo)
+
und -
als binäre
Operatoren addieren beziehungsweise subtrahieren
<<
kann man den linken Operanden um soviele Bit nach
links schieben (shift), wie der rechte Operand angibt; von rechts her werden
Nullen eingefügt. Dementsprechend schiebt >>
nach rechts; von
links her werden Nullen eingefügt (falls der linke Operand positiv
ist) oder Einsen (wenn negativ).
<
und >
vergleichen auf ,,kleiner`` und
,,größer``; <=
und >=
auf ,,kleiner gleich`` und
,,größer gleich``.
==
vergleicht zwei Werte auf Gleichheit, !=
auf
Ungleichheit
&
verknüpft zwei Operanden bitweise mit UND
^
werden zwei Operanden
bitweise XOR
(exklusives ODER)
verknüpft.
|
werden zwei Operanden
bitweise OR
(ODER)
verknüpft.
&&
ist ein logisches UND
||
ist ein logisches ODER
?:
hat drei Operanden:
Ausdruck1?
Ausdruck2:
Ausdruck3
wertet Ausdruck1 aus; wenn dieser true ergibt (also
ungleich 0 ist), dann wird Ausdruck2 berechnet und dessen Ergebnis
geliefert; ansonsten Ausdruck3.
Der Ausdruck i=10 let "k=i?2:3"
weist demnach an k den Wert
2 zu.
=
dient, wie bereits in den
Beispielen gezeigt, der Zuweisung.
Ähnlich wie in C gibt es davon noch etliche Varianten, die eine
Zuweisung an den ersten Operanden einer anderen Operation zusammenfassen,
nämlich:
+=
, -=
, *=
, /=
,
%=
, <<=
, >>=
,
&=
, ^=
, |=
.
Dabei entspricht a+=b
dem Ausdruck a=a+b
; analog ist
a-=b
identisch mit a=a-b
, und so fort.
,
Ausdruck2
Weil solche Ausdrücke von links her zusammengefaßt werden, kann man
auch längere Ketten bilden:
Ausdruck1,
Ausdruck2,
Ausdruck3,
...,
Ausdruck n
führt alle Ausdrücke aus, und liefert das Ergebnis des letzten.
AnyWare@Wachtler.de