class: center, middle ## Programmieren mit BASH: Grundlagen ### Hauke Goos-Habermann #### https://goos-habermann.de --- ### Über mich - Entwickler des
Softwareverteilungssystems m23
- Organisator der
Kieler Open Source und Linux Tage
-
Dienstleister zu m23, Linux und Freier Software
- Softwareentwicklung (PHP, BASH, C/C++, JS, Python und was sonst so gebraucht wird...) - Administration - Schulungen - Support - Beratung - quasi **alles**, *was mit Linux zu tun hat* - Wöchentlicher Livestream *"Jean und Hauke Show"* auf https://www.youtube.com/c/LinuxGuides - *"Nicht der Weisheit letzter Schluß"* mit **beruflichen** oder **privaten Projekten** auf
tube.tchncs.de/c/ndwls
und
youtube.com/@nichtderweisheit
- Verwendet BASH für Automatisierungsaufgaben und Co. --- ### BASH? Eher ***häßliche*** **Skriptsprache**, die quasi auf jeder Linux-Distribution **vorinstalliert** ist und die durch den "unerschöflichen" Vorrat an Kommandozeilenprogrammen für (fast) jeden Zweck verwendet werden kann. Beispiel
fotos-sortieren.sh
* Verzeichnisse nach jpg-Dateien durchsuchen * Bilder anzeigen * Taste für Löschen oder Ok wählen * Bildverzeichnis löschen oder verschieben Beispiel"fotos":
fotos.zip
--- ### Variablen(-ersetzung) BASH unterscheidet **keine Variablentypen**: In BASH wird z.B. eine Zahl intern als Text abgespeichert und die Interpretation geschieht erst durch eine Funktion oder ein Kommandozeilenprogramm. ```bash # Deklaration string='Hallo Welt!' zahl=23 zahl2='24' # "Richtige" Verwendung: Mit Variablenersetzung echo "$string: $zahl / $zahl2" # "Falsche" Verwendung: Unveränderte Ausgabe echo '$string: $zahl / $zahl2' ``` --- ### Ausgaben umlenken Unter Linux und anderen Unix-artiken Systemen gibt es
Kanäle
, über die Programme
Informationen ausgeben
oder von diesen
lesen
. ```bash # Direkte Ausgabe im Terminal echo 'Hallo Welt!' echo 'Hallo Welt!' > /dev/stdout # Eine Meldung auf den Fehlerkanal umleiten echo 'Eine Fehlermeldung' > /dev/stderr # Fehlerausgabe/-kanal (Nr. 2) in's "Schwarze Loch" umleiten, aber # normale Meldungen durchlassen mkdir "$gut" 2> /dev/null # Alle Ausgaben in's "Schwarze Loch" umleiten type mc &> /dev/null # Text in eine Datei schreiben (neu anlegen bzw. überschreiben) echo 'Ein Text' > /tmp/text.txt # Fehler an eine Logdatei anhängen (Doppelpfeil ">>") tar cfvz /tmp/back.tar.gz /etc 2>> /tmp/backup.log ``` --- ### Eingaben und Pipes *cat* zeigt Informationen direkt an oder gibt diese an andere Programme weiter und liest Eingaben über die **Standard*eingabe***. ```bash # Inhalt der Textdatei über die Standardeingabe an cat übergeben cat < /tmp/text.txt ``` Über eine Pipe ("|") kann die **Ausgabe** eines Programms **als Eingabe** an ein **anderes übergeben** werden: ```bash # Die Ausgabe von *echo* als Eingabe an *cat* übergeben echo 'Hallo!' | cat # Ausgabe mit *grep* nach Zeilen, die eine 2 enthalten, filtern # und mit *sort* sortieren echo '2b 1 2a 3' | grep 2 | sort -n ``` --- ### Funktionen In der BASH können Funktionen geschrieben werden, um **wiederkehrende Aufgaben** (mit Parametern) verfügbar zu machen. ```bash # Funktion deklarieren function add() { # Parameter 1 und 2 auslesen und benannten Variablen zuweisen a=$1 b=$2 # Summe berechnen expr $a + $b } # Parameter übergeben add 2 5 ``` --- ### Schleifen Schleifen
wiederholen Teile eines Quelltextes
und können dabei z.B. Parameter anpassen. ```bash # *seq* generiert eine Liste mit den Zahlen von 1 bis 10, die mit der # for-Schleife einzeln der Variablen $i zugewiesen werden for i in `seq 1 10` do # Aktuellen Wert von $i ausgeben echo $i done # Alternativ auch als Einzeiler mit $(...) statt `...`: for i in $(seq 1 10); do echo $i; done # Zählvariable deklarieren i=1 # Überprüfen, ob $i <= 10 ist und nur dann die Schleife laufen lassen while [ $i -le 10 ] do echo $i # $i hochzählen mit *$[ ... ]* i=$[ $i + 1 ] done ``` --- ### Rückgabewerte und if-Verzweigungen Jedes Programm gibt beim Beenden einen **Rückgabewert** über die Variable "$?" zurück. **0** bedeutet **"fehlerfreie Ausführung"**, davon **abweichende Werte** sind **Fehlercodes**. Über **if-else**-Verzweigungen wird entweder der eine oder der andere (else) Codeteil ausgeführt, insofern es einen zweiten gibt. ```bash # *true* generiert den Rückgabewert 0, *false* 1 true # Wenn *$?* ungleich (*n*ot *e*qual) 0 ist, ist ein Fehler aufgetreten if [ $? -ne 0 ] then echo "Fehler aufgetreten!" else echo "Alles Ok!" fi ``` --- ### Tastatur lesen und case-Verzweigungen Mit ***case*** kann der Wert einer Variablen mit einzelnen Werten abgeglichen und entsprechende Codeteile ausgeführt werden. Zudem kann ein **Standardfall** angegeben werden, der **ausgeführt** wird, wenn bei der sequentiellen Abarbeitung **keine Übereinstimmung** gefunden werden konnte. ```bash # Eine Taste einlesen read -p 'a, b oder was anderes?' absonst case "$absonst" in 'a') echo 'Das ist ein "a"' ;; # Einer der mit "|" angegebenen Fälle 'b' | 'c') echo 'Das ist ein "b" oder "c"' ;; # Wenn sonst noch nichts paßt *) echo "Das ist was anderes \"$absonst\"" ;; esac ``` --- ### Textdateien editieren *sed* (**s**tream **ed**itor) editiert Textdateien anhand von einfachen Kommandos. ```bash # Datei erstellen echo 'aaaa bbbbb c' > /tmp/sed.txt # Jedes "a" zu einem "x" machen, nur das erste "b" zu einem "y" sed -e 's/a/x/g' -e 's/b/y/' /tmp/sed.txt # Zeilen, die mit "a" anfangen oder "b" aufhören, löschen sed -e '/^a/d' -e '/b$/d' /tmp/sed.txt # Zeilen löschen, die nur "c" enthalten und die Quelldatei direkt ändern: sed -i '/^c$/d' /tmp/sed.txt ``` --- class: center, middle ### Informationen zu mir und meinen Dienstleistungen, m23, ... ### https://goos-habermann.de