Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
Shell-Programmierung von Jürgen Wolf
Einführung, Praxis, Referenz
Buch: Shell-Programmierung

Shell-Programmierung
782 S., mit CD, 44,90 Euro
Rheinwerk Computing
ISBN 3-89842-683-1
gp Kapitel 2 Variablen
  gp 2.1 Grundlagen
    gp 2.1.1 Zugriff auf den Wert einer Variablen
    gp 2.1.2 Variablen-Interpolation
  gp 2.2 Zahlen
    gp 2.2.1 Integer-Arithmetik (Bourne-Shell, Bash und Korn-Shell)
    gp 2.2.2 Integer-Arithmetik (Bash und Korn-Shell only)
    gp 2.2.3 bc – Rechnen mit Fließkommazahlen und mathematische Funktionen
  gp 2.3 Zeichenketten
    gp 2.3.1 Stringverarbeitung
    gp 2.3.2 Erweiterte Funktionen für Bash und Korn-Shell
  gp 2.4 Quotings und Kommando-Substitution
    gp 2.4.1 Single und Double Quotings
    gp 2.4.2 Kommando-Substitution – Back Quotes
  gp 2.5 Arrays (Bash und Korn-Shell only)
    gp 2.5.1 Werte an Arrays zuweisen
    gp 2.5.2 Eine Liste von Werten an ein Array zuweisen (Bash)
    gp 2.5.3 Eine Liste von Werten an ein Array zuweisen (Korn-Shell)
    gp 2.5.4 Zugreifen auf die einzelnen Elemente eines Arrays
  gp 2.6 Variablen exportieren
  gp 2.7 Umgebungsvariablen eines Prozesses
  gp 2.8 Shell-Variablen
  gp 2.9 Automatische Variablen der Shell
    gp 2.9.1 Der Name des Shellscripts – $0
    gp 2.9.2 Die Prozessnummer des Shellscripts – $$
    gp 2.9.3 Der Beendigungsstatus eines Shellscripts – $?
    gp 2.9.4 Die Prozessnummer des zuletzt gestarteten Hintergrundprozesses – $!
    gp 2.9.5 Weitere vordefinierte Variablen der Shell
    gp 2.9.6 Weitere automatische Variablen für Bash und Korn-Shell


Rheinwerk Computing

2.2 Zahledowntop

Wenn Mathematik nie Ihr Parade-Fach war, dann haben Sie etwas mit der Shell (und dem Autor ;-)) gemeinsam. Die Bourne-Shell kann nicht mal die einfachsten arithmetischen Berechnungen durchführen. Zur Verteidigung muss man allerdings sagen, dass der Erfinder der Shell nie im Sinn gehabt hat, eine komplette Programmiersprache zu entwickeln. Bei der Bash und der Korn-Shell hingegen wurden einfache arithmetische Operationen eingebaut, obgleich diese auch nur auf einfache Integer-Berechnungen beschränkt sind. Werden Fließkommazahlen benötigt, dann müssen Sie auf ein externes Tool umsteigen, z. B. den Rechner bc.


Rheinwerk Computing

2.2.1 Integer-Arithmetik (Bourne-Shell, Bash und Korn-Shell)  downtop

Zwar bieten Ihnen die Bash und die Korn-Shell erheblich komfortablere Alternativen als die Bourne-Shell, aber wenn Sie nicht genau wissen, in welcher Shell Ihr Script verwendet wird, dann sind Sie mit der Integer-Arithmetik der Bourne-Shell gut beraten. Ihre Scripts werden dann auf jeder Shell laufen, also sowohl in der Bourne- und Korn-Shell als auch in der Bash.

Zum Rechnen in der Bourne-Shell wird der alte UNIX-Befehl expr verwendet. Beim Aufruf dieses Befehls können reguläre Ausdrücke, Zeichenketten-, arithmetische oder Vergleichsausdrücke als Parameter übergeben werden. Daraufhin erhalten Sie das Ergebnis des Ausdrucks auf die Standardausgabe.

you@host >  expr 8 / 2
4
you@host >  expr 8 + 2
10

Das Ganze lässt sich natürlich auch mit einem Shellscript nutzen:

# Demonstriert die Verwendung von expr
# zum Ausführen arithmetischer Ausdrücke
# Name : aexpr
var1=100
var2=50
expr $var1 + $var2
expr $var1 – $var2

Das Script bei der Ausführung:

you@host > ./aexpr
150
50

Hierzu gibt es eigentlich nicht viel zu sagen. Wichtig ist es jedoch, in Bezug auf expr noch zu erwähnen, dass beim arithmetischen Ausdruck Leerzeichen zwischen den einzelnen Operatoren und Operanden unbedingt erforderlich sind!

Wer schon weitere expr-Ausdrücke probiert hat, wird beim Multiplizieren auf Probleme gestoßen sein. Ähnliche Schwierigkeiten dürften auch mit den Klammern auftreten.

you@host >  expr 8 * 5
expr: Syntaxfehler
you@host >  expr ( 5 + 5 ) * 5
bash: syntax error near unexpected token `5'

Hier haben Sie das Problem, dass die Shell ein * eben als Datei-Expansion behandelt und bei den Klammern gern eine weitere Subshell öffnen würde. Damit beides außer Kraft gesetzt wird, müssen Sie hier nur vor den kritischen Zeichen ein Backslash setzen.

you@host > expr 8 \* 5
40
you@host > expr \( 5 + 5 \) \* 5
50

Wollen Sie den Inhalt einer Berechnung in einer Variablen abspeichern, benötigen Sie eine Kommando-Substitution. Was das genau ist, erfahren Sie noch in Abschnitt 2.4. Wie Sie das hier einsetzen können, soll Ihnen aber nicht vorenthalten werden.

# Demonstriert, wie Sie einen arithmetischen expr-Ausdruck
# in einer Variablen speichern können
# Name : aexpr2
var1=100
var2=50
# Dies wird als Kommando-Substitution bezeichnet
var3=`expr $var1 + $var2`
echo $var3

Durch die Klammerung des Ausdrucks rechts vom Gleichheitszeichen (hier durch zwei Gravis-Zeichen) wird das, was durch die Anweisung expr normalerweise auf dem Bildschirm ausgegeben wird, an der entsprechenden Stelle in der Zuweisung eingesetzt und der links stehenden Variablen zugewiesen.

var3=`expr $var1 + $var2`

Richtig befriedigend dürfte expr für keinen sein, denn die Verwendung bleibt ausschließlich auf Integerzahlen und die arithmetischen Operatoren +, –, *, / und % beschränkt. Als Alternative und als eine gewisse Erleichterung bietet es sich an, mit dem UNIX-Kommando bc zu arbeiten. Hierauf wird anschließend in Abschnitt 2.2.3 eingegangen.


Rheinwerk Computing

2.2.2 Integer-Arithmetik (Bash und Korn-Shell only)  downtop

Klar, die Bash und die Korn-Shell können das wieder besser, schließlich stellt jede dieser Shells eine Erweiterung der Bourne-Shell dar, wobei die Bash ja ohnehin alles kann. Es stehen auf jeden Fall mehrere Möglichkeiten zur Auswahl.

you@host > ((z=5+5))
you@host > echo $z
10

Hier wurden doppelte Klammerungen verwendet, um der Shell Bescheid zu geben, dass es sich hier um einen mathematischen Ausdruck handelt. Im Beispiel haben Sie eine Variable »z« definiert, welche den Wert von 5 + 5 erhält. Hiermit können Sie jederzeit auf den Inhalt von »z« zurückgreifen. Neben dieser Möglichkeit können Sie auch eine andere Schreibweise verwenden, die allerdings denselben Effekt hat.

you@host > y=$((8+8))
you@host > echo $y
16
you@host > echo $((z+y))
26

Und zu guter Letzt hat die Bash noch einen Spezialfall der Integer-Arithmetik mit eckigen Klammern eingebaut.

you@host > w=$[z+y]
you@host > echo $w
26
you@host > w=$[(8+2)*4]
you@host > echo $w
40

Mir persönlich gefällt diese Version mit den eckigen Klammern am besten, aber wem nützt das, wenn man sein Script auch in der Korn-Shell ausführen muss. Dass die doppelte Klammerung nicht unbedingt leserlich wirkt, liegt auf der Hand. Deshalb finden Sie bei der Korn-Shell und der Bash auch das Builtin-Kommando let.

let

Das Kommando let wertet arithmetische Ausdrücke aus. Als Argumente werden hierbei mit Operatoren verbundene Ausdrücke verwendet.

you@host > let z=w+20
you@host > echo $z
60

Allerdings besteht zwischen let und den doppelten Klammerungen – abgesehen von der Anwendung – kein Unterschied. Die Verwendung von let im Beispiel oben entspricht exakt folgender Klammerung:

you@host > z=$((w+20))
you@host > echo $z
60

let dient hier lediglich dem Komfort. Zur Anschauung let in einem Shellscript:

# Beispiel demonstriert das Kommando let
# Name: alet
varA=100
varB=50
let varC=$varA+$varB
echo $varC

Was bei diesem Shellscript auffällt, ist, dass das Kommando let erst beim eigentlichen arithmetischen Ausdruck verwendet wird. Zwar können Sie let auch vor den einzelnen Variablen setzen, doch das ist im Grunde nicht nötig.

Wenn Sie mit einem let-Aufruf mehrere Ausdrücke gleichzeitig auswerten lassen, oder wenn Sie der besseren Lesbarkeit wegen Leerzeichen einstreuen wollen, sind die Ausdrücke jeweils in doppelte Anführungszeichen einzuschließen, wie bspw. in

you@host > let "a=5+5" "b=4+4"
you@host > echo $a
10
you@host > echo $b
8

typeset

Das Builtin-Kommando typeset oder declare kann Ihnen hier (und in vielen anderen Fällen auch) das Shell-Leben noch etwas komfortabler gestalten. Mit beiden Kommandos können Sie entweder eine Shell-Variable erzeugen und/oder die Attribute einer Variablen setzen. Verwenden Sie z. B. die Option –i auf einer Variablen, so werden diese in der Shell als Integer-Variable behandelt und gekennzeichnet.

you@host > typeset -i a b c
you@host > b=10
you@host > c=10
you@host > a=b+c
you@host > echo $a
20

Was hier auch gleich ins Auge sticht: Dank der Integer-Deklaration entfällt beim Rechnen mit den Integer-Variablen auch das $-Zeichen bei der Anwendung.

# Beispiel mit typeset
# Name : atypeset
typeset -i c
a=5
b=2
c=a+b
echo $c
c=a*b
echo $c
c=\(a+b\)*2
echo $c

Wie schon beim Kommando let ist es nicht nötig, alle Variablen als Integer zu deklarieren, wie Sie dies schön im Shellscript »atypeset« sehen können. Es reicht aus, wenn Sie das Ergebnis als Integer kennzeichnen. Den Rest übernimmt die Shell wieder für Sie.


Hinweis   Bei jeder Version von Integer-Arithmetik, abgesehen von expr, wird das Sternchen auch als Rechenoperator erkannt und muss nicht erst als Expansions-Kandidat mit einem Backslash unschädlich gemacht werden. Die Klammern müssen Sie allerdings nach wie vor mit einem Backslash schützen.



Tabelle 2.1   Arithmetische Operatoren (Bash und Korn-Shell)

Operator Bedeutung
+, –, *, / Addition, Subtraktion, Multiplikation, Divison
% Rest einer ganzzahligen Divison (Modulo-Operator)
var+=n var–=n var*=n var/=n var%=n Kurzformen für +, –, *, /, % Kurzform für bspw. Addition var+=n ist gleichwertig zu var=var+n
var>>n Bitweise Linksverschiebung um n Stellen
var<<n Bitweise Rechtsverschiebung um n Stellen
>>= <<= Kurzformen für die Links- bzw. Rechtsverschiebung << und >>
var1&var2 Bitweises UND
var1^var2 Bitweises exklusives ODER (XOR)
var1|var2 Bitweises ODER
~ Bitweise Negation
&= ^= |= Kurzformen für bitweise UND, exklusives ODER sowie ODER (&, | und ^)


Rheinwerk Computing

2.2.3 bc – Rechnen mit Fließkommazahlen und mathematische Funktionetoptop

Wohl keine der oben vorgestellten Lösungen erschien Ihnen sonderlich elegant. Daher würde sich als Alternative und auf jeden Fall als Erleichterung das UNIX-Kommando bc anbieten.

bc ist ein Quasi-Tischrechner, der von der Standardeingabe (Tastatur) zeilenweise arithmetische Ausdrücke erwartet und das Ergebnis wiederum zeilenweise auf der Standardausgabe (Bildschirm) ausgibt. bc arbeitet im Gegensatz zum verwandten Programm dc mit der gewohnten Infix-Schreibweise und verlangt kein Leerzeichen zwischen Operatoren und Operanden. Außerdem muss der arithmetische Operator * vor der Shell nicht geschützt werden. Entsprechendes gilt auch für runde Klammern.

bc ist eigentlich kein Befehl, sondern eher eine Art Shell mit einer Präzisions-Kalkulationssprache. Allerdings lässt sich bc auch gut in jeder Shell als Befehl verwenden. Die Argumente schiebt man dem Befehl mithilfe einer Pipe unter. Und gegenüber den Rechenoperationen, die sonst so in der Shell möglich sind, hat bc den Vorteil, dass es mit Fließkommazahlen rechnet.

Die Verwendung von bc ist allerdings auf den ersten Blick etwas gewöhnungsbedürftig, aber bei regelmäßiger Anwendung sollten keine größeren Probleme auftreten. Hier die Syntax:

Variable=`echo "[scale=n ;] Rechenoperation" | bc [-l]`

Angaben in eckigen Klammern sind optional. Mit scale=n können Sie die Genauigkeit (n) der Berechnung angeben. Die Rechenoperation besteht aus Ausdrücken, die verbunden sind mit Operatoren. Hierbei können alle bekannten arithmetischen Operatoren verwendet werden (inklusive der Potenzierung mit ^ und dem Bilden einer Quadratwurzel mit sqrt()).

Wird bc mit der Option –l (für library) aufgerufen, können Sie auch auf Funktionen einer mathematischen Bibliothek (math library) zugreifen. In Tabelle 2.2 finden Sie einige Funktionen (x wird dabei durch entsprechenden Wert bzw. eine Variable ersetzt).


Tabelle 2.2   Zusätzliche mathematische Funktionen von bc mit der Option -l

Funktion Bedeutung
s(x) Sinus von x
c(x) Cosinus von x
a(x) Arcustangens von x
l(x) Natürlicher Logaritmus von x
e(x) Exponentialfunktion e hoch x

Ihnen bc bis ins Detail zu erläutern, ist wohl zu viel des Guten, aber zumindest verfügen Sie damit über ein Werkzeug für alle wichtigen mathematischen Probleme, das Sie selbstverständlich auch für Integer-Arithmetik einsetzen können.

Hier ein Shellscript mit einigen Anwendungsbeispielen von bc (inklusive der math library).

# Demonstriert die Verwendung von bc
# Name : abc
echo Rechnen mit bc
varA=1.23
varB=2.34
varC=3.45
# Addieren, Genauigkeit 3 nach dem Komma
gesamt=`echo "scale=2 ; $varA+$varB+$varC" | bc`
echo $gesamt
# Quadratwurzel
varSQRT=`echo "scale=5 ; sqrt($varA)" | bc`
echo $varSQRT
# Einfache Integer-Arithmetik
varINT=`echo "(8+5)*2" | bc`
echo $varINT
# Trigonometrische Berechnung mit der math library -l
varRAD=`echo "scale=10 ; a(1)/45" | bc -l`
echo -e "1° = $varRAD rad"
# Sinus
varSINUS45=`echo "scale=10 ; s(45*$varRAD)" | bc -l`
echo "Der Sinus von 45° ist $varSINUS45"

Das Shellscript bei der Ausführung:

you@host > ./abc
Rechnen mit bc
7.02
1.10905
26
1° = .0174532925 rad
Der Sinus von 45° ist .7071067805

Zahlen konvertieren mit bc: bin/hex/dec

Zum Konvertieren von Zahlen können Sie ebenfalls auf das Kommando bc setzen. Hierzu finden Sie bei bc zwei Variablen, ibase und obase. Das i steht für Input (Eingabe der Zahlenbasis), o für Output (gewünschte Ausgabe der Zahlenbasis) und base für die gewünschte Zahlenbasis. Beiden Variablen kann ein Wert von 2–16 übergeben werden. Der Standardwert beider Variablen entspricht unserem Dezimalsystem, also 10. Wenn Sie ibase und obase gemeinsam benutzen, müssen Sie beim Umrechnen von bspw. binär nach dezimal die Reihenfolge beachten, weil sonst das Ergebnis nicht stimmt (siehe das folgende Beispiel).

# Demonstriert die Konvertierung verschiedener Zahlensysteme
# Name : aconvert
varDEZ=123
echo $varDEZ
# Dez2Hex
var=`echo "obase=16 ; $varDEZ" | bc`
echo $var
# Dez2Oct
var=`echo "obase=8 ; $varDEZ" | bc`
echo $var
# Dez2Bin
var=`echo "obase=2 ; $varDEZ" | bc`
echo $var
# Bin2Dez – Reihenfolge von obase und ibase beachten
dez=`echo "obase=10 ; ibase=2 ; $var" | bc`
echo $dez

Das Script bei der Ausführung:

you@host > ./aconvert
123
7B
173
1111011
123


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
 << zurück
  
  Zum Katalog
Zum Katalog: Shell-Programmierung
Shell-Programmierung
bestellen
 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-Server






 Linux-Server


Zum Katalog: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Katalog: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Katalog: Linux Handbuch






 Linux Handbuch


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de