Aus den Shell-Tipps und dem Guru-Training kennen Sie viele nützliche Kommandozeilentools. Die können Sie in kleinen Shell-Skripten zu leistungsfähigen Miniprogrammen bündeln. Im einfachsten Fall lassen Sie damit mehrere Befehle automatisch nacheinander ablaufen, doch Skripte haben noch mehr zu bieten.
Nützliche Shell-Skripte zu schreiben, erfordert in erste Linie ein wenig Kreativität – daneben müssen angehende Shell-Programmierer auch wissen, wie man solche Skripte grundsätzlich erstellt: Da geht es um den formalen Aufbau von Skriptdateien, die Syntax der Standard-Shell bash. Die ist aber schnell erlernt, und wenn Sie diese einmal beherrschen, sind Ihnen kaum Grenzen gesetzt.
Ausgangspunkt jedes (nützlichen) neuen Shell-Skripts ist immer der Wunsch, eine Aufgabe zu automatisieren. Leztztlich geht es darum, Zeit zu sparen und langweilige Wiederholungen zu meiden. Nehmen wir als Einstiegsbeispiel an, dass Sie sich regelmäßig auf der Shell über den freien Arbeitsspeicher und den freien Festplattenplatz auf der Partition, die /home/ enthält, informieren möchten. In der Shell würden Sie dazu die zwei Befehle free und df -h /home verwenden. Machen Sie genau das (warum auch immer) mehrmals am Tag, überlegen Sie sich mit der Zeit, dass hier ein Shell-Skript die Tipparbeit reduzieren könnte.
Alias für Kurzbefehle
Für diese noch sehr einfache Aufgabenstellung können Sie auch die Alias-Funktion nutzen, die in die Shell eingebaut ist: Geben Sie z. B.
alias i="free; df -h /home"
ein, können Sie anschließend einfach den Befehl i verwenden, um die beiden Kommandos nacheinander abarbeiten zu lassen. Das Semikolon trennt die beiden Befehle voneinander. Das funktioniert aber nur in der Shell, in der Sie dieses Alias gesetzt haben. Tragen Sie die Zeile am Ende der Datei ~/.bashrc ein, ist der neue Befehl auch in allen zukünftig geöffneten Shell-Fenstern verfügbar.
Hier soll es aber um Skripte gehen, also basteln Sie statt des Alias eine Skriptdatei. Dazu benötigen Sie einen Texteditor, z. B. Kate oder gedit; wenn Sie den Konsoleneditor vi kennen (und bedienen können), geht es damit schneller und ohne Zusatzfenster. In eine neue, leere Datei tragen Sie die Zeile
free; df -h /home
ein und speichern – schon haben Sie die erste Skriptdatei erstellt. Diese müssen Sie noch ausführbar machen, z. B. über das Kommando
chmod a+x Dateiname
Liegt die Datei im aktuellen Arbeitsverzeichnis und heißt z. B. i.sh, können Sie diese anschließend mit
./i.sh
ausführen – der führende Punkt ist wichtig, damit die Shell die Skriptdatei findet, weil sie (zumindest standardmäßig) nicht im aktuellen Ordner sucht, sondern eine über die Shell-Variable PATH festgelegte Liste von Ordnern nach ausführbaren Programmen durchsucht. Wie im Beispiel, ist es üblich, Shell-Skripten die Dateiendung .sh zu geben – nötig ist das aber nicht, Sie können auch ganz ohne Endung arbeiten und die Datei z. B. nur i nennen.
In Shell-Skripten verzichtet man (u. a. wegen einer besseren Lesbarkeit) meist darauf, mehrere Befehle in eine Zeile zu schreiben. Außerdem ist es sinnvoll, in der ersten Zeile der Skriptdatei anzugeben, welche Shell das Skript ausführen soll. Schließlich bietet es sich an, Befehle zu kommentieren: Bei kleineren Skripten ist das überflüssig, aber komplexere Skriptdateien bleiben damit auch Jahre später noch verständlich. Einen Kommentar ergänzen Sie in einer Zeile hinter der Raute (#). Die so veränderte Version der Datei hat diesen Aufbau:
#!/bin/bash free # Arbeitsspeicher df -h /home # Plattenplatz
Die erste Zeile enthält einen speziellen Kommentar; hinter #! (mit zusätzlichem Ausrufezeichen) steht der Pfad zur Shell (Bash), und damit sagen Sie dem System, dass die Bash – und nicht etwa eine andere Shell – das Skript ausführen soll. Diese Zeile sollten Sie an den Anfang jeder Skriptdatei stellen.
Ändern Sie nachträglich eine schon mit chmod ausführbar gemachte Skriptdatei, bleibt die Eigenschaft erhalten; es ist also nicht nötig, erneut ein chmod-Kommando einzugeben.
Pipelines
Schon aus dem normalen Shell-Einsatz kennen Sie vielleicht die mit dem Zeichen “|” erzeugten Pipes. Ein kleines Beispiel für dessen Einsatz ist die Such nach dem größten Unterordner im aktuellen Verzeichnis: Mit
du -sm *
lassen Sie sich für jede Datei und jeden Ordner im aktuellen Arbeitsverzeichnis den belegten Speicher in MByte ausgeben. Das erzeugt eine Ausgabe wie in Listing 1.
Listing 1
Unsortierte “du”-Ausgabe
$ du -sm * 0 00_anzeigen 5 01_layout 1 02_layoutueberpruefung 1 03_schlussredaktion 1 04_layoutendcheck 1 05_pdf-endcheck 0 06_final 18 07_dvd-labels 210 0_vorlagen 1 10_seitenplan 0 11_online 151 html 276 orig_txt
Die Ausgabe ist informativ, leidet aber bei einer längeren Liste daran, dass sie unsortiert ist. Sie könnten die Programmausgabe in eine Ausgabedatei umleiten, indem Sie an den Befehl > datei anhängen und die so erzeugte Datei dann mit sort -n datei numerisch (-n) sortiert ausgeben – einfacher geht es mit einer Pipe. Dazu kombinieren Sie die beiden Kommandos, schreiben also
du -sm * | sort -n
Die Pipe erspart Ihnen somit die Verwendung einer temporären Datei für Zwischenergebnisse. Listing 2 zeigt den Effekt im direkten Vergleich: Die größten Ergebnisse stehen jetzt am Ende der Ausgabe. Auch solche Pipes können Sie in ein Shell-Skript einbauen.
Listing 2
Sortierte “du”-Ausgabe
$ du -sm * | sort -n 0 00_anzeigen 0 06_final 0 11_online 1 02_layoutueberpruefung 1 03_schlussredaktion 1 04_layoutendcheck 1 05_pdf-endcheck 1 10_seitenplan 5 01_layout 18 07_dvd-labels 151 html 210 0_vorlagen 276 orig_txt
Pipes können zudem aus mehr als zwei Kommandos bestehen, Ihrem Erfindungsreichtum sind also keine Grenzen gesetzt.
Komplexere Skripte
Ein längeres Beispielskript, das aber immer noch lediglich mehrere Befehle nacheinander ausführt, sehen Sie in Listing 3: 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 2016-04-30 und verschiebt alle Bilder von der Karte in diesen Ordner. Mit Smartphones funktioniert das übrigens in der Regel nicht, weil sich viele aktuelle Geräte beim Anschließen über USB nicht mehr als Datenträger, sondern als PTP– oder MTP-Gerät anmelden (Abbildung 1). Wie Sie mit ein paar Änderungen trotzdem auf die Smartphone-Fotos zugreifen können, verrät der Kasten Zugriff aufs Smartphone.

Abbildung 1: Viele Smartphones erlauben keinen direkten Zugriff auf das Dateisystem, so z. B. das Samsung Galaxy S5, das die Wahl zwischen MTP- und PTP-Verbindungen lässt.
Listing 3
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
In der ersten Zeile steht wieder der Hinweis, dass die Shell /bin/bash das Skript ausführen soll.
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 oder dem Smartphone ausprobieren möchten, müssen Sie diesen Pfad anpassen. Nach dem Anschließen der Kamera wird diese eingebunden. Unterhalb von /media/ oder in einem Ordner in Ihrem Home-Verzeichnis finden Sie dann einen neuen Ordner, der meist eine Kurzbezeichnung Ihres Kameramodells oder der Herstellers als Namen trägt. (Geben Sie den Befehl mount ein, um eine Liste aller eingehängten Datenträger zu sehen.)
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 2016-04-30 erfolgt. Würden Sie also in der Shell direkt date +%Y-%m-%d eingeben, würde das Tool das aktuelle Datum im Format 2016-04-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/2016-04-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.
Bearbeiten Sie ein Shell-Skript im Editor, 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 2) und im Konsolen-Editor vi.

Abbildung 2: KDEs Editor Kate erkennt Shell-Skripte und aktiviert beim Bearbeiten das Syntax Highlighting.
Zugriff aufs Smartphone
Wenn Sie klassisch (also über das Einhängen ins Dateisystem) auf die Smartphone-Fotos zugreifen möchten, können Sie dazu eines der Programmpakete gphotofs (für PTP) oder mtpfs (für MTP) nachinstallieren. Unter Kubuntu gelingt das mit
sudo apt-get install Paketname
Bei OpenSuse sind die nötigen Repositorys für die Pakete noch nicht eingetragen, darum ist die One-Click-Installation über die Paketsuche am leichtesten [4, 5].
Sind die Tools einmal installiert, legen Sie nur einen Mountpoint (einen leeren Ordner, z. B. mtp/ direkt in Ihrem Home-Verzeichnis) an und geben dann das Kommando mtpfs mtp bzw. gphotofs mtp ein. Das Programm kümmert sich dann um den Verbindungsaufbau, und im Anschluss haben Sie über den gewählten Ordner Zugriff auf die via PTP und MTP bereitgestellten Dateien (Abbildung 3).
Die Ordnerstruktur, die via PTP/MTP sichtbar wird, ist komplexer als bei einfachen Digitalkameras. Der Mountpoint enthält meist zwei Unterordner, einen für den fest verbauten Speicher und einen für die eingesetzte SD-Karte. Abhängig von den Einstellungen der Foto-App finden Sie dann in einem dieser Ordner das Verzeichnis DCIM, welches in einem weiteren Unterordner dann endlich Zugriff auf die Fotos gewährt. Auf unserem Testgerät haben wir die Bilder in store_00020002/DCIM/Camera/ gefunden.
Um den Zugriff zu beenden, verwenden Sie das Kommando fusermount -u mtp/ (wobei Sie mtp/ durch den von Ihnen beim Aufruf von gphotofs oder mtpfs gewählten Mountpoint ersetzen).
Bash als Programmiersprache
Richtige Programmiersprachen können aber mehr, als nur einfache Befehlssequenzen abzuarbeiten. So helfen Fallunterscheidungen (so genannte If-Then-Else-Konstruktionen), Schleifen (mit dem Spezialfall der Zählschleife) sowie Prozeduren bzw. Funktionen, den Ablauf variabler zu gestalten.
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. Die Idee ist dabei, dass die Shell eine Bedingung prüft und abhängig vom Ergebnis (das wahr oder falsch sein kann) den einen oder anderen Zweig der If-Then-Else-Konstruktion abarbeitet. 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 – den Rückgabewert des jeweils letzten Befehls lesen Sie über $? aus:
$ 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 darum 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 if … fi eine Rückwärtsschreibung von case ist.
For-Schleife
Die Bash kennt keine klassische Zählschleife, die eine Variable von einem Anfangs- zu einem Endwert hochzählt. Stattdessen gibt es etwas, das in anderen Sprachen als For-Each-Schleife bezeichnet wird. So können Sie z. B. schreiben:
for entry in *
do
if [ ! -e $entry ]
then echo "$entry gibt es nicht"
continue
fi
if [ -f $entry ]
then echo "Datei $entry"
fi
if [ -d $entry ]
then echo "Verzeichnis $entry"
fi
done
Das Sternchen ist das normale Wildcard-Zeichen; in der Schleife nimmt die Variable $entry nacheinander alle Namen von Dateien und Verzeichnissen im aktuellen Ordner an.
Die For-Schleife beenden Sie mit done. Neu in diesem Beispiel ist auch das Ausrufezeichen: Es kehrt den Wahrheitswert eines Tests um. Einen Test auf Ungleichheit zweier Variablen können Sie also z. B. als [ ! "$x" = "$y" ] schreiben – allerdings gibt es dafür auch die lesbarere Form [ "$x" != "$y" ].
Ein Klassiker der Bash-Skripte (auch hier in EasyLinux) ist das Konvertieren von Bildern, etwa in zusätzliche Vorschaubilder. Wollen Sie z. B. eine Fotogalerie erstellen, werden Sie meist auch kleine Versionen der Bilder benötigen. Sie können dazu einfach einen Vierzeiler (minipics.sh) schreiben:
#!/bin/bash for Bild in *.jpg; do Mininame=$( basename $Bild .jpg )_s.jpg echo Erzeuge Vorschaubild für $Bild convert "$Bild" -resize 100x100 "$Mininame" done
In der Schleife erhält die Variable Bild nacheinander die Namen aller JPG-Dateien (mit Endung .jpg und führt für jede dieser Dateien die Befehle im Inneren der Schleife aus: Zunächst wird der Name für die Vorschaudatei bestimmt: Hier nutzt das Skript die $(...)$-Konstruktion, die Sie bereits im ersten Skript gesehen haben. Innerhalb der Klammern entfernt der Befehl basename $Bild .jpg vom Ursprungsdateinamen die Endung (aus foto1.jpg wird also foto1), an das Ergebnis wird _s.jpg angehängt (so dass im Beispiel foto1_s.jpg entsteht. Diesen Namen speichert der Befehl in der Variablen Mininame.
Schließlich erledigt das Tool convert (aus dem ImageMagick-Paket, das Sie eventuell nachinstallieren müssen) die Umwandlung. Es verwendet die Variablen Bild und Mininame, in denen die Namen der Quell- und Zieldateien stehen, und sorgt über die Option -resize 100x100 dafür, dass die neue Datei Abmessungen hat, die 100 x 100 Pixel nicht überschreiten; die Seitenverhältnisse bleiben dabei erhalten: Ein Bild der Größe 600 x 400 Pixel wird darum auf 100 x 67 Pixel verkleinert. Abbildung 4 zeigt, wie das Skript arbeitet.
Zählschleife
Über einen kleinen Trick können Sie auch eine Zählschleife programmieren. Zwar gibt es keine spezielle Syntax für das Hochzählen, aber dafür können Sie das Programm seq verwenden, das eine Sequenz aus Zahlen generiert:
$ seq 5 8 5 6 7 8
Über die schon zweimal gesehene $(...)-Konstruktion können Sie diese Zahlenwerte in einen anderen Befehl integrieren. Um in einer Variablen $i von 1 bis 100 zu zählen, schreiben Sie:
for i in $(seq 1 100) do ... done
Das Programm seq können Sie auch mit drei Argumenten aufrufen, das mittlere steht dann für die Veränderung, die in jedem Schritt stattfindet – normal wird immer 1 addiert. Dieser mittlere Wert darf auch negativ sein, was aber voraussetzt, dass der Anfangswert größer als der Endwert ist:
$ echo $( seq 20 -3 0 ) 20 17 14 11 8 5 2
Wie Sie an diesem Beispiel sehen, wird der Endwert eventuell nicht erreicht; nach 2 wäre der nächste Wert -1, der ist aber zu klein, darum taucht er nicht mehr in der Ausgabe auf.
While-Schleife
Als letzte Schleife erwähnen wir die While-Schleife, sie hat die Syntax
while Bedingung doBefehle done
und führt die Befehle im Inneren aus, solange die Bedingung erfüllt ist – sie prüft dabei immer am Anfang. Sie können leicht ein interaktives Skript erstellen, das Eingaben von der Tastatur liest und abbricht, wenn Sie z. B. exit eingeben:
read x while [ "$x" != "exit" ] do echo Eingabe war $x read x done
Es verwendet das Kommando read, das einen oder mehrere Variablennamen als Argumente akzeptiert. Geben Sie (wie oben) nur einen Namen an, landet die ganze eingegebene Zeile in der Variable. Wenn Sie mehrere Variablen angeben, zerlegt read Ihre Eingabe in Teile und weist diese den Variablen zu. (Trennzeichen sind das Leer- und das Tabulatorzeichen.) Wenn es in diesem Fall mehr Teile als Variablen gibt, landet der Rest in der letzten Variable.
Funktionen
Zum Abschluss stellen wir noch Shell-interne Funktionen vor: Diese können Sie einfach in einer C-ähnlichen Syntax definieren und dann direkt in der Shell oder in einem Skript verwenden.
Anders als in normalen Programmiersprachen erhalten Funktionsargumente keine Namen, sondern werden über ihre Aufrufposition angesprochen; das funktioniert wie beim Aufruf eines Shell-Skripts:
function addiere {
echo Berechne $1 plus $2
ergebnis=$(( $1 + $2 ))
echo Summe ist $ergebnis
}
Die Funktion können Sie mit zwei Argumenten aufrufen, z. B. addiere 5 20, und Sie erhalten dann die Ausgabe
Berechne 5 plus 20 Summe ist 25
Bei der Gelegenheit haben Sie auch gleich gesehen, wie Sie in der Shell rechnen können; Sie packen dazu den mathematischen Ausdruck einfach in $((...)). Es gibt hier nur Integer-Werte, Sie können also keine Zahlen mit Nachkommastellen verwenden. Auch bei der Berechnung von Brüchen (mit /) entstehen immer ganze Werte, die Shell führt eine Division mit Rest durch:
$ echo $(( 5/3 )), $(( 6/3 )) 1, 2
Hilfe im Netz
Um das Rad nicht mehrfach neu zu erfinden, können Sie im Internet auf Suche nach Skripten für bestimmte Aufgaben gehen: Viele Anwender veröffentlichen ihre Skript-Lösungen, und es fördert das Verständnis, wenn Sie ein solches Skript herunterladen und nachvollziehen, was es tut. Eine Sammlung von Skripten und Links zu anderen Webseiten über Skripte finden Sie auf der Shelldorado-Seite [1] (Abbildung 5).

Abbildung 5: Die Webseite “shelldorado.com” bietet unter anderem eine umfassende Linksammlung zu Shell-Skripten.
Darüber hinaus hat der Rheinwerk-Verlag eine vollständige HTML-Version des Buchs “Shell-Programmierung” von Jürgen Wolf ins Netz gestellt [2], die gedruckte Version hat 780 Seiten, so dass ausreichend Lektüre für Ihre Ausbildung zum Shell-Programmierer vorhanden ist.
Wenn Sie bei eigenen Recherchen auf fremde Shell-Skripte stoßen und darin einzelne Befehle nicht verstehen, hilft die Webseite ExplainShell [3] weiter: Dort können Sie ein (kurzes oder auch komplexes) Kommando eingeben und erhalten dann eine ausführliche Erklärung zu Aufbau und Funktion (Abbildung 6).
Glossar
-
PTP
-
Das Picture Transfer Protocol ist ein älterer Standard für den Zugriff auf Digitalkameras, der ohne die Einbindung des Geräts als Datenträger arbeitet.
-
MTP
-
Das Media Transfer Protocol ist eine von Microsoft und Canon erdachte Weiterentwicklung von PTP, die z. B. auch den Transfer von MP3-Dateien auf entsprechende Player erlaubt.
Infos
[1] Heiners Shelldorado: http://www.shelldorado.com/
[2] Jürgen Wolf, “Shell-Programmierung. Einführung, Praxis, Referenz”, http://openbook.rheinwerk-verlag.de/shell_programmierung/
[3] ExplainShell: http://explainshell.com/
[4] gphotofs für OpenSuse: https://software.opensuse.org/package/gphotofs
[5] mtpfs für OpenSuse: https://software.opensuse.org/package/mtpfs




