Inhalt


Übersicht

Bash Basics

Warum Bash?

Das erste Skript

Control flow

Noctua2

Orbitale plotten

Dark Mode

Warum Bash?

Die Auswahl an Programmier- und Skriptsprachen ist inzwischen riesig geworden. Zwischen modern(er)en Sprachen, wie Julia und Python, ist die Shellsprache bash bis heute weit benutzt. Die Konstrukte und Strukturen wirken inzwischen oft veraltet. Warum hält sich also bash immer noch?

Der große Vorteil ist wohl die Einfachheit in der Alltagsnutzung. Die Unix-Betriebssysteme sind zusammen mit dieser Art von Skriptsprachen entstanden und gewachsen. Der Umgang mit Dateien und Strukturen des Betriebssystems ist besonders gut optimiert. Als Beispiel: nehmen wir an, wir wollen eine Aktion an allen Dateien eines Ordners vornehmen. Nutzen wir dazu das interne if-Konstrukt, könnte das so aussehen.

for i in $(ls); do
    ... Logik an $i ...
done

Der Befehl ls gibt hier die Inhalte des aktuellen Ordners aus. Durch das Konstrukt $( ) wird die Ausgabe in einen String umgewandelt. Die einzelnen Einträge werden dann in der Variable $i gespeichert und können dann benutzt werden. Wollen wir an die Namen zum Beispiel bck anhängen, um sie als veraltet zu markieren, können wir folgende Logik nutzen.

for i in $(ls); do
    mv $i bck_$i
done

Das erste Skript

Widmen wir uns zunächst der Verwendung von Strings und Integern in Variablen.

mia@surface-mia:~$ i="Hallo Welt!"
mia@surface-mia:~$ echo $i
Hallo Welt!

Das Beispiel zeigt ein einfaches “Hallo Welt” Programm. Es kann entweder direkt in die Shell eingegeben, oder in einem kurzen Skript abgespeichert werden.

mia@surface-mia:~$ cat hallo_welt.sh

i="Hallo Welt!"
echo $i

mia@surface-mia:~$ bash hallo_welt.sh
Hallo Welt!

Die übliche Dateiendung für Skripte ist .sh. In dieser Form müssen Skripte immer mit dem Programm bash aufgerufen werden, das dann die Befehle interpretiert. Wir können diese Information jedoch auch in das Skript schreiben. Dazu ergänzen wir am Anfang die sogenannte Shebang-Zeile.

#!/usr/bin/bash

Die Zeichen #! signalisieren dem Betriebssystem, dass nun der Pfad zum Programm, mit dem das Skript geöffnet werden soll, folgt. Hier ist der Pfad zum ausführbaren Datei bash /usr/bin/bash. Der Befehl which gibt die Pfade aller installierten Programme aus.

mia@surface-mia:~$ which bash
/usr/bin/bash

Wollen wir nun unser Skript ausführen, so bekommen wir folgende Ausgabe.

mia@surface-mia:~$ ./hallo_welt.sh
bash: ./hallo_welt.sh: Keine Berechtigung

Zur Sicherheit dürfen Dateien auf Unix-Betriebssystemen ohne weiteres nicht ausgeführt werden. Dazu werden allen Dateien eine Reihe von Berechtigungen zugewiesen. Diese können mit dem Befehl ls -l eingesehen werden.

mia@surface-mia:~/Test$ ls -lh
insgesamt 8,0K
-rw-r--r-- 1 mia mia   24 29. Nov 13:46 hallo_welt.sh
drwxr-xr-x 2 mia mia 4,0K 29. Nov 13:58 Ordner

Wir erhalten ein Auflistung aller Inhalte im akutellen Verzeichnis. Ganz links werden die Rechte aufgelistet.

- || r w x || r w x || r w x

Die erste Stelle kennzeichnet den Datentypen. Unser Skript - eine Textdatei - erhält dabei das Zeichen -, während ein Ordner durch d gekennzeichnet ist. Es folgen drei Zeichen, die die Rechte des Besitzers darstellen. Jede Datei wird von einem Benutzer angelegt, der die Datei dann besitzt. Dieser Nutzer soll meist die Berechtigung haben Dateien zu lesen und zu ändern, während andere Nutzer des selben Systems die Dateien nur lesen, oder gar nicht sehen sollen. Das erste Zeichen kennzeichnet die Leseberechtigung ('r' für read), also darf diese Datei betrachtet werden. Das zweite Zeichen zeigt die Schreibberechtigung an ('w' für write), darf diese Datei geändert werden. Das dritte Zeichen kodiert die Ausführberechtigung ('x' für eXecute), darf die Datei gestartet werden.

Bei diesen Berechtigungen werden nun drei Gruppen unterschieden. 1. Der Besitzer (“owner”) 2. Die Gruppe (“group”) 3. Alle Anderen Nutzer (“others”) Auf Nutzergruppen soll hier aber nicht weiter eingegangen werden.

Für uns interessant ist natürlich die Ausführberechtigung. Zum Verändern der Rechte, können wir das Programm chmod nutzen. Wir wollen das Ausführen erlauben, also die eXecute Berechtigung - gekennzeichnet durch ein 'x' - hinzufügen. Der Befehl dazu ist einfach chmod +x. Das ganze wollen wir auf eine bestimmte Datei anwenden, damit ergibt sich insgesamt:

chmod +x hallo_welt.sh

Versuchen wir jetzt erneut unser Skript auszuführen, bekommen wir den erwarteten Output.

mia@surface-mia:~/Test$ ./hallo_welt.sh
Hallo Welt!

Damit haben wir unser erstes Bashskript geschrieben.

Control flow

Beschäftigen wir uns nun mit den Steuerungskonstruktuen in bash. Analog zu anderen Skriptsprachen, haben wir die üblichen Tools, wie if und for Blöcke zur Verfügung. Die Syntax kann etwas umständlich wirken, erlaubt aber auch einige nützliche Anwendungen. Schauen wir uns nochmal den Code aus der Einführung an.

for i in $(ls); do
    mv $i bck_$i
done

Die Struktur eines range-for Konstrukts in bash sieht immer folgendermaßen aus.

for [Variable] in [Liste]
do
    ... Logik ...
done

Zwei Befehle können dabei durch ein ; in eine Zeile geschrieben werden. Wir haben auch bereits angesprochen, dass innerhalb eines $(...) Aufrufs verschiedene Befehle ausgeführt und die Ausgabe in einen durch Leerzeichen getrennten String umgewandelt werden kann. Dabei werden auch Zeilenumbrüche in Leerzeichen umgewandelt. Führen wir im home-Verzeichnis zum Beispiel den ls Befehl aus und weisen die Ausgabe einer Variable test zu

test=$(ls)

bekommen wir als Ausgabe der Variable (echo $test) zum Beispiel den folgenden String.

Bilder Dokumente Downloads go Musik Schreibtisch
Test Videos Vorlagen

Bei der Zuweisung der Einträge in der range-for Schleife, werden dabei durch Leerzeichen getrennte Zeichenketten als Einträge betrachtet. Die Regel keine Leerzeichen in Datei-, Ordner- und Programmnamen zu nutzen, ist im Zusammenhang mit Skripten also besonders wichtig.

Eine zweite Regel wird hier auch ersichtlich. Variablen müssen immer mit einem $-Zeichen gekennzeichnet sein, außer bei einer Zuweisung. Im Code der for-Schleife weisen wir der Laufvariable i durch den Befehl i in $(ls) die Einträge zu. Wollen wir diese Einträge in der Schleife nutzen, so tun wir dies mit $i. Auch bei der direkten Zuweisung test=$(ls) müssen wir die Variable in echo $test mit dem $-Zeichen kenntlich machen. Ein weiterer häufiger Fehler bei Zuweisungen ist das Setzen von Leerzeichen. Bei Variablenzuweisung dürfen keine Leerzeichen zwischen dem = und den Namen stehen. Der Aufruf test = $(ls) wäre also ungültig.

Beschäftigen wir uns jetzt mit den if-Konstrukten. Die grundlegende Form einer Abfrage sieht wie folgt aus.

if
then
    ... Logik ...
elif
then
    ... Logik ...
else
    ... Logik ...
fi

Bei der Syntax gilt es also auf die then und das abschließende fi statement zu achten.

Die Bedingungen müssen in eckigen Klammern geschrieben sein.