AA_PO-20949-123RF-Ivan_Mikhaylov_123RF-Muscheln.jpg

© Ivan Mikhaylov, 123RF

Programme in der Shell

Bash-Skripte sind Programme

09.07.2013
Wer regelmäßig mit der Shell arbeitet, wird leicht zum Programmierer: Schreiben Sie mehrere Shell-Befehle in eine Textdatei und machen diese ausführbar, haben Sie schon Ihr erstes Shell-Skript entwickelt. Die Shell bietet als Programmiersprache aber noch viel mehr.

Viele Shell-Skripte enthalten einfach nur diverse Befehle, die nacheinander laufen sollen. Ein Beispiel dafür ist das Skript in Listing 1: Rufen Sie es nach dem Anstöpseln einer Digitalkamera (oder dem Einstecken einer Speicherkarte) auf, erzeugt es automatisch einen neuen Unterordner mit einem Namen der Form 2013-06-30 und verschiebt alle Bilder von der Karte in diesen Ordner.

Listing 1

Bilder kopieren

#!/bin/bash
CAMERA=/media/camera/DCIM/100XYZAB
ZIEL=$HOME/Pictures/Import
DATE=$( date +%Y-%m-%d )
mkdir $ZIEL/$DATE
mv -v $CAMERA/* $ZIEL/$DATE/
sync
echo Bilder kopiert.

Schauen wir uns das Listing Zeile für Zeile an:

#!/bin/bash

Die erste Zeile enthält gar keinen Befehl, sondern einen Kommentar; hinter #! steht der Pfad zur Shell (Bash), und damit sagen Sie dem System, dass die Bash das Skript ausführen soll. Diese Zeile sollten Sie an den Anfang jeder Skriptdatei stellen.

CAMERA=/media/camera/DCIM/100XYZAB

Die folgende Zeile definiert eine Variable CAMERA und weist ihr den Wert /media/camera/DCIM zu. Wenn Sie das Skript mit Ihrer eigenen Kamera ausprobieren möchten, müssen Sie diesen Pfad anpassen. Nach dem Anschließen der Kamera wird diese eingebunden. Unterhalb von /media/ finden Sie dann einen neuen Ordner, der meist eine Kurzbezeichnung Ihres Kameramodells oder der Herstellers als Namen trägt. Auf der obersten Ebene des Kameradateisystems gibt es einen Ordner DCIM/, der ein weiteres Unterverzeichnis enthält – im Beispiel 100XYZAB; bei Ihnen wird es anders heißen. Setzen Sie den korrekten Pfad in der obigen Zeile ein, wenn Sie das Skript testen möchten.

ZIEL=$HOME/Pictures/Import

Ähnlich wie CAMERA den Ort speichert, in dem die Bilder auf der Kamera liegen, ist auch ZIEL eine Variable, in die Sie das Verzeichnis eintragen, in welches das Skript die Bilder kopieren soll. In diesem Beispiel gehen wir davon aus, dass es in Ihrem Home-Verzeichnis (das sich über $HOME ansprechen lässt) einen Ordner Pictures gibt – und darin einen Unterordner Import. Falls das nicht der Fall ist, ist es auch nicht tragisch, denn der übernächste Befehl wird diese Verzeichnisse erzeugen.

DATE=$( date +%Y-%m-%d )

Dieses Kommando ist komplexer. Schauen wir zunächst in die Klammern: Dort steht das Kommando date +%Y-%m-%d. Ohne Argumente gibt date das aktuelle Datum und die Uhrzeit aus. Mit den Angaben hinter dem Pluszeichen definieren Sie ein Format – %Y-%m-%d sorgt dafür, dass die Ausgabe im Format 2011-09-30 erfolgt. Würden Sie also in der Shell direkt date +%Y-%m-%d eingeben, würde das Tool das aktuelle Datum im Format 2011-09-30 ausgeben. Die Konstruktion $( ... ) nimmt nun die Ausgabe dieses Befehls und macht daraus ein Argument. Am Anfang steht ja noch der Zuweisungsbefehl DATE=. Das gesamte Kommando schreibt also in die Variable DATE das aktuelle Datum.

mkdir -p $ZIEL/$DATE

Jetzt wird ein neuer Ordner erstellt – der Pfad setzt sich aus $ZIEL, dem Verzeichnistrenner / und $DATE zusammen. Beachten Sie hier, dass Sie beim Setzen einer Variable den Namen ohne Dollarzeichen benutzen, beim Zugriff auf den Inhalt hingegen ein Dollarzeichen voranstellen müssen. Wenn $HOME z. B. den Wert /home/user hat, ergibt sich über die Definitionen von ZIEL und DATE ein Befehl der Form mkdir -p /home/user/Pictures/Import/2011-09-30. Die Option -p für das mkdir-Kommando sorgt dafür, dass eventuell fehlende Verzeichnisse "auf dem Weg" (also .../Pictures/Import und .../Pictures) gleich mit erzeugt werden, so dass dieses Kommando nicht fehlschlagen kann.

mv -v $CAMERA/* $ZIEL/$DATE/

Das vorvorletzte Kommando verschiebt dann alle Dateien im Bilderordner der Kamera in den Bilderordner auf Ihrer Festplatte; die Option -v sorgt dafür, dass mv die Namen aller verschobenen Dateien auf der Konsole ausgibt, damit Sie den Fortschritt verfolgen können.

sync

Mit sync sorgen Sie schließlich dafür, dass Sie nach Ausführen des Skripts die Kamera einfach abstöpseln können, ohne Datenverlust zu riskieren.

echo Bilder kopiert.

Zum Schluss gibt es noch eine Statusmeldung. Damit Sie das Skript verwenden können, speichern Sie es (z. B. als copycam.sh in Ihrem Home-Verzeichnis) und machen es mit

chmod a+x copycam.sh

ausführbar. Dann können Sie es später mit

~/copycam.sh

aufrufen. Wenn Sie die Datei (mit Root-Rechten) in das Verzeichnis /usr/local/bin/ kopieren, können Sie die Pfadangabe auch weglassen, also in der Shell einfach copycam.sh eingeben.

Wenn Sie ein Shell-Skript im Editor bearbeiten, kommen Sie übrigens in der Regel in den Genuss von Syntax Highlighting, der Editor hebt Schlüsselwörter, Klammern und Variablennamen farbig hervor. Das funktioniert z. B. in KDEs Editor Kate (Abbildung 1) und im Konsolen-Editor vi.

Abbildung 1: KDEs Editor Kate erkennt Shell-Skripte und aktiviert beim Bearbeiten das Syntax Highlighting.

Bash als Programmiersprache

Richtige Programmiersprachen können aber mehr, als nur einfache Befehlssequenzen abzuarbeiten. In der Einführung ins Programmieren ab Seite 38 haben Sie Fallunterscheidungen (If-Then-Else-Konstruktionen), Schleifen (mit dem Spezialfall der Zählschleife) sowie Prozeduren bzw. Funktionen kennengelernt. All das gibt es auch in der Shell.

Fallunterscheidungen haben in der Shell die folgende Syntax:

if Bedingung
then Befehle
else Befehle
fi

Die Befehlsworte sind also if, then, else und fi (eine rückwärts geschriebene Form von if, die das Ende der Fallunterscheidung anzeigt). Der Else-Fall muss nicht vorhanden sein. Das folgende Beispielskript exist prüft, ob eine Datei existiert:

#!/bin/bash
if test "$1" = ""
then echo "$0: mit Dateinamen aufrufen!"; exit
fi
if test -e $1
then echo $1 existiert
else echo $1 existiert nicht
fi

Der erste Test prüft mit dem in die Shell eingebauten Kommando test, ob das Skript überhaupt mit einem Argument aufgerufen wurde ($1 ist das erste Argument; wenn es das nicht gibt, ist $1 ein leerer String). Ist kein Argument vorhanden, bricht das Programm mit exit ab. Das funktioniert, weil das Skript in einer "Sub-Shell", also einem eigenen Shell-Prozess läuft.

Zum "Then-Fall" gehören also zwei Kommandos, die hier mit einem Semikolon voneinander getrennt sind – Sie können sie alternativ auch in mehrere Zeilen des Programms schreiben. Oft stehen auch then und else alleine in jeweils einer Zeile, und die Kommandos für die beiden Fälle folgen darunter. Eine üblichere (wenn auch weniger kompakte Schreibweise) der ersten Fallunterscheidung ist damit die folgende:

if test "$1" = ""
then
  echo "$0: mit Dateinamen aufrufen!"
  exit
fi

Ein direkter Vergleich mit if "$1" = "" ist übrigens nicht möglich: Die Bedingung in einer Fallunterscheidung muss immer ein Kommando sein, dessen Rückgabewert die Shell dann prüft. Zum Beispiel gibt es die beiden Programme true und false, die beide keine sichtbare Funktion haben, aber die Rückgabewerte 0 und 1 produzieren:

$ true; echo $?
0
$ false; echo $?
1
$ if true; then echo Ja; else echo Nein; fi
Ja

Zurück zum exist-Skript: Der zweite Test ruft test -e $1 auf. Wenn Sie in die Dokumentation zu test schauen (das geht mit help test, weil test ein Shell-Builtin, also ein fest in die Shell eingebautes Kommando ist), sehen Sie, dass das Kommando über -e dateiname prüft, ob eine bestimmte Datei vorhanden ist.

Um eine Syntax zu erlauben, die stärker an normale Programmiersprachen erinnert, können Sie statt des Schlüsselworts test auch öffnende und schließende eckige Klammern verwenden, z. B.

if [ "$1" = "" ]

Beachten Sie dabei, dass die Klammern zu den übrigen Komponenten der Zeile mit einem Leerzeichen Abstand halten müssen; der Ausdruck

if ["$1" = ""]

enthält also zwei Syntaxfehler. Für andere Shells als die Bash gibt es sogar ein Programm /bin/[, welches genauso arbeitet. Sie könnten damit auch den merkwürdigen Ausdruck

if /bin/[ "$1" = "" ]

verwenden, wenn Sie die Leser Ihrer Skripte irritieren möchten. Kombinieren Sie die Klammerschreibweise und das Aufteilen auf mehrere Zeilen, entsteht hübscher Code, der intuitiv zu verstehen ist:

if [ "$1" = "" ]
then
  echo "$0: mit Dateinamen aufrufen!"
  exit
fi

(Haben Sie $0 bemerkt? Darüber können Sie den Namen der Skript-Datei herausfinden.) Wollen Sie mehr als zwei Fälle prüfen, können Sie ein weiteres Schlüsselwort verwenden: elif steht für "else if", ein Beispiel:

if [ "$1" = "a" ]
then echo "a"
elif [ "$1" = "b" ]
then echo "b"
elif [ "$1" = "c" ]
then echo "c"
else echo "Weder a noch b noch c"
fi

Case-Befehl

Für mehrere Tests, die alle den Inhalt derselben Variable prüfen, können Sie auch den case-Befehl nutzen, der diese Aktionen übersichtlicher macht:

case "$1" in
  "a")
    echo "a" ;;
  "b")
    echo "b" ;;
  *)
    echo "Weder a noch b" ;;
esac

Hinter jedem Fall steht eine schließende Klammer; dann folgen einer oder mehrere Befehle, und der Code für einen Fall muss mit doppelten Semikola (;;) enden. Der gesamte case-Ausdruck endet mit esac, was wieder (wie bei iffi eine Rückwärtsschreibung von case ist.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

  • Alltagsaufgaben mit Skripten beschleunigen
    Ein Themenschwerpunkt Beschleunigung darf die Shell nicht auslassen, denn der Grundtenor unserer Guru-Training-Rubrik ist doch, dass Sie auf der Shell schneller als mit GUI-Tools arbeiten. Wir geben ein paar nützliche Beispiele.
  • Die Kraft der Muschel
    Microsofts neue PowerShell greift auf die Bibliotheken des .NET-Frameworks zurück und verfügt so über einen riesiger Fundus von Funktionen und Objekten. Ist sie dadurch einer traditionellen Shell wie der Bash überlegen?
  • Erste Schritte mit Bash-Skripten
    Das Programmieren von Shell-Skripten ist keine Hexerei. Schon mit wenigen Grundkenntnissen sparen Sie durch das Automatisieren alltäglicher Aufgaben viel Zeit.
  • Ohne Crash durch die Bash
    Mit der Bourne-Again-Shell schreiben Linux-Anwender Skripte, die nervige und stupide Aufgaben automatisieren – etwa um auf dem Notebook Strom einzusparen.
  • Einführung in die Bash-Programmierung
    Skripte sollen meist wiederkehrende oder lästige Arbeiten automatisieren. Die Standard-Shell Bash stellt Ihnen dazu eine ganze Reige von Funktionen bereit. Dieser Artikel erklärt, wie Sie ihre eigenen Shell-Skripte schreiben.
Kommentare

Infos zur Publikation

title_2014_04

Digitale Ausgabe: Preis € 9,80
(inkl. 19% MwSt.)

EasyLinux erscheint vierteljährlich und kostet EUR 9,80. Weitere Informationen zum Heft finden Sie auf der EasyLinux-Homepage.

Das EasyLinux-Jahresabo mit Prämie kostet ab EUR 33,30. Details zum EasyLinux-Jahresabo finden Sie im Medialinx-Shop.

NEU: DIGITALE AUSGABEN FÜR TABLET & SMARTPHONE

HINWEIS ZU PAYPAL: Die Zahlung ist auch ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!      

Tipp der Woche

Ubuntu 14.10 und VirtualBox
Ubuntu 14.10 und VirtualBox
Tim Schürmann, 08.11.2014 18:45, 0 Kommentare

Wer Ubuntu 14.10 in einer virtuellen Maschine unter VirtualBox startet, der landet unter Umständen in einem Fenster mit Grafikmüll. Zu einem korrekt ...

Aktuelle Fragen

PCLinuxOS Version 2014.08 "FullMonty" Umstellung auf deutsch
Karl-Heinz Welz, 19.12.2014 09:55, 3 Antworten
Hallo, liebe Community, ich bin 63 Jahre alt und möchte jetzt nach Jahrzehnten Windows zu Linux...
ICEauthority
Thomas Mann, 17.12.2014 14:49, 2 Antworten
Fehlermeldung beim Start von Linux Mint: Could not update ICEauthority file / home/user/.ICEauth...
Linux einrichten
Sigrid Bölke, 10.12.2014 10:46, 5 Antworten
Hallo, liebe Community, bin hier ganz neu,also entschuldigt,wenn ich hier falsch bin. Mein Prob...
Externe USB-Festplatte mit Ext4 formatiert, USB-Stick wird nicht mehr eingebunden
Wimpy *, 02.12.2014 16:31, 0 Antworten
Hallo, ich habe die externe USB-FP, die nur für Daten-Backup benutzt wird, mit dem YaST-Partition...
Steuern mit Linux
Siegfried Markner, 01.12.2014 11:56, 2 Antworten
Welches Linux eignet sich am besten für Steuerungen.