Name des Skriptes testen, ob es schon ein Programm mit dem gewünschten Skriptnamen gibt type mein_Skript.sh Ausführbar machen und aufrufen chmod +x /pfad/zu/mein_Skript.sh starten /pfad/zu/mein_Skript.sh ./mein_Skript.sh bash mein_Skript.sh Skript verfügbar machen ~/bin/ ~/.profile ls -l /usr/local/bin sudo chown root /usr/local/bin/mein_Skript.sh sudo chgrp root /usr/local/bin/mein_Skript.sh sudo chmod 755 /usr/local/bin/mein_Skript.sh Die Shebang Shebang: #!/bin/bash /bin/sh in der Shebang. /bin/sh hingegen ist laut POSIX-Standard ein Muss. Die Bash ist eine komplexere Shell, die nicht auf allen unixoiden Systemen zur Verfügung steht. Unter Ubuntu ist /bin/sh ein symbolischer Link auf die Dash. 1.) Kommentare einfügen 2.) Variablen – Teil 1 2.1.) Variablen belegen 2.2.) Variablen lesen 2.3.) Variablen löschen 2.4.) Variablen abgrenzen 2.5.) Quoting 3.) Befehle 4.) Variablen 5.) Maskierung mit Backslashes 6.) Variablen – Teil 2 7.) Abschneiden von Mustern 8.) Umgebungsvariablen 9.) Rechnen mit der Shell 10.) Arrays 10.1.) Arrays belegen 10.2.) Arrays auslesen 10.3.) Arrays löschen 10.4.) Assoziative Arrays 11.) Interaktion mit dem Benutzer 11.1.) Ausgabe von Text 11.2.) Einlesen von Eingaben 12.) Umleitungen 13.) Das Test-Kommando 14.) Programmführung 14.1.) If-Else-Anweisung 14.2.) Case-Anweisungen 14.3.) Schleifen 15.) Parameter an ein Skript übergeben 16.) Funktionen #!/bin/bash #Hallo Welt Skript echo "Hallo Welt" 11.2.) Einlesen von Eingaben 1.) Kommentare einfügen # Dies ist ein Kommentar 2.) Variablen – Teil 1 2.1.) Variablen belegen Im Gegensatz zu vielen anderen Programmiersprachen darf man bei der Shell keine Leerzeichen vor und nach dem Zuweisungszeichen = verwenden! message=hallo message="hallo Welt" 2.2.) Variablen lesen echo "$message" 2.3.) Variablen löschen unset message 2.4.) Variablen abgrenzen Gelegentlich kann es der Fall sein, dass man Variablen innerhalb einer Zeichenkette verwenden möchte. echo "$message" echo "$messagelolo" echo "${message}lolo" 2.5.) Quoting 3.) Befehle echo Hallo, Welt echo "Hallo, Welt" echo * -> bin include lib local man sbin share src var echo "*" -> * echo "Dies ist eine > mehrzeilige Ausgabe. > Man hält es nicht für möglich." 4.) Variablen foo="Hallo, Welt" echo "$foo" echo $foo -> Hallo, Welt date +%A Der Parameter %A zeigt den ausgeschriebene Wochentag an Montag Auf einem deutschen System ist diese Ausgabe wie erwartet auf Deutsch. Man kann nun die Variable $LC_ALL LC_ALL=C date +%A Monday 5.) Maskierung mit Backslashes¶ echo \$foo $foo 6.) Ausgaben in eine Variable schreiben Befehlssubstitution #!/bin/bash #Ausgaben in Variable schreiben #Variablendefinition suchwort=player liste=$(apropos $suchwort) echo " Player-Liste:" echo "$liste" #!/bin/bash #Ausgaben in Variable schreiben #Variablendefinition suchwort=player liste=$(apropos $suchwort) echo " Player-Liste:" echo "$liste" 7.) Abschneiden von Mustern¶ Eine gewöhnungsbedürftige, aber doch sehr nette Funktion ist das Herausschneiden bestimmter Muster aus der Zeichenkette einer Variablen. Schnitt-Funktionen Funktion Erklärung ${variable%muster} Entfernt rechts das kleinste passende Stück. ${variable%%muster} Entfernt rechts das größte passende Stück ${variable#muster} Entfernt links das kleinste passende Stück. ${variable##muster} Entfernt links das größte passende Stück pfadname="/var/www/index.html" echo $pfadname /var/www/index.html echo "Pfad: ${pfadname%/*}" Pfad: /var/www echo "Dateiname: ${pfadname##*/}" Dateiname: index.html 8.) Umgebungsvariablen HOME Enthält das Homeverzeichnis des Benutzers. PATH Suchpfad für Kommandos. PWD Enthält das Aktuelle Verzeichnis. ? Enthält den Exitstatus des letzten Kommandos 9.) Rechnen mit der Shell pingu@ubuntu:~$ echo $((100 / 3)) 33 pingu@ubuntu:~$ x="62" pingu@ubuntu:~$ echo $(($x + 12)) 74 pingu@ubuntu:~$ ((x++)) pingu@ubuntu:~$ echo "$x" 63 pingu@ubuntu:~$ a=$((3 + 4 * 2)) pingu@ubuntu:~$ echo "$a" 11 pingu@ubuntu:~$ b=$(((3 + 4) * 2)) pingu@ubuntu:~$ echo "$b" 14 10.) Arrays 10.1.) Arrays belegen Um einen Wert in ein Array zu schreiben, ist es nötig, den Index mit anzugeben. Allgemein sieht das folgendermaßen aus: Arrayname[i]=Wert Soll ein neues Array mit mehreren Werten auf einmal belegt werden, dann bietet sich folgende Schreibweise an: Arrayname=(Dies sind vier Werte) Es können auch Elemente an das Ende eines Arrays angefügt werden. Das Ende ist dabei der höchste bereits existierende Index: Arrayname+=(all diese sieben Elemente werden einzeln angefügt) 10.2.) Arrays auslesen echo ${array[2]} Wird als Index ein „@“ oder „*“ angegeben, ${array[*]} oder ${array[@]}: Alle Elemente mit Nachbearbeitung wie Globbing oder Word-Splitting. "${array[*]}": Kein Globbing, Elemente getrennt durch erstes Zeichen aus $IFS, Endergebnis ist ein Argument. "${array[@]}": Kein Globbing, jedes Element wird ein eigenes Argument. echo ${array[*]} Hallo, Welt! bin boot dev etc home lib lost+found media mnt opt proc root run sbin srv sys tmp usr var Noch ein paar Worte und Leerzeichen. 10.3.) Arrays löschen unset array 10.4.) Assoziative Arrays declare -A meinarray meinarray=( [zwei]="Zweiter Wert" [drei]="Dritter Wert" [vier]="Vierter Wert" ) meinarray[eins]="Ein Wert" echo ${meinarray[eins]} 11.) Interaktion mit dem Benutzer 11.1.) Ausgabe von Text #!/bin/bash #Hallo Welt Skript echo "Hallo Welt" 11.2.) Einlesen von Eingaben #!/bin/bash #Begrüßung read -p "Geben sie ihren Namen ein:" name echo Hallo: $name 12.) Umleitungen Operator Erklärung > Dient der Umleitung der Standardausgabe in eine Datei. >> Dient ebenfalls der Umleitung in eine Datei, hängt jedoch die Ausgabe an eine bereits bestehende Datei an anstatt diese zu überschreiben. | Mit dem Pipeoperator lässt sich die Ausgabe eines Kommandos als Eingabe für ein anderes verwenden. < Statt von der Standardeingabe (Tastatur) wird aus einer Datei gelesen 13.) Das Test-Kommando -d Verzeichnis Ist wahr, wenn "Verzeichnis" existiert. -e Datei Ist wahr, wenn Datei existiert. -f Datei Ist wahr, wenn reguläre Datei existiert. -w Datei Ist wahr, wenn die Datei existiert und Schreibzugriff erlaubt ist. -x Datei Ist wahr, wenn Datei existiert und Ausführbar ist. -n String Ist wahr, wenn String nicht leer ist. (Bsp. eine Variable) -z String Ist wahr, wenn String leer ist. (Bsp. eine Variable) String1 = String2 Ist wahr, wenn String1 gleich String2 ist. Zahl1 -eq Zahl2 Ist wahr, wenn Zahl1 gleich Zahl2 ist. (-eq = equal) Zahl1 -lt Zahl2 Ist wahr, wenn Zahl1 kleiner Zahl2 ist. (-lt = less than) Zahl1 -gt Zahl2 Ist wahr, wenn Zahl1 größer Zahl2 ist. (-gt = greater than) Zahl1 -le Zahl2 Ist wahr, wenn Zahl1 kleiner oder gleich Zahl2 ist. (-le = less or equal) Zahl1 -ge Zahl2 Ist wahr, wenn Zahl1 größer oder gleich Zahl2 ist. (-ge = greater or equal) Zahl1 -ne Zahl2 Ist wahr, wenn Zahl1 nicht gleich Zahl2 ist. (-ne = not equal) ! foo Ist wahr, wenn foo falsch ist, also eine Negation. 14.) Programmführung 14.1.) If-Else-Anweisung if [ Test-Bedingung ] then Befehl... fi if [ Test-Bedingung ] then echo "Ok, alles in Ordnung." else echo "Ahrg...Fehler." fi if [ Test-Bedingung ] then Befehl... elif [ Test-Bedingung ] then Befehl... else Befehl... fi #!/bin/bash echo "Wie ist Ihr Name?" read ANTWORT if [ "$ANTWORT" == "root" ] then echo "Hallo, Administrator." else echo "Hallo, Anwender." fi Ein Beispiel zeigt, wie man auf die Existenz einer Datei hin prüft und entsprechend dem Ergebnisse eine Meldung dazu ausgibt. #!/bin/bash #Dateitest if [ -f /home/Pingu/test.txt ] then echo "Die Datei test.txt in Pingus Home ist da." else echo "Die Datei test.txt in Pingus Home fehlt." fi Oder das ganze wird mit einer elif-Konstruktion erweitert. #!/bin/bash # Dateitest if [ -f /home/Pingu/test.txt ] then echo "Die Datei test.txt in Pingus Home ist da." elif [ -d /home/Pingu/test.txt ] then echo "test.txt ist ein Verzeichnis" else echo "Die Datei test.txt in Pingus Home fehlt" fi 14.2.) Case-Anweisungen #!/bin/bash dat="$1" # Schneide vor Dateiendung ab: ext=${dat/*./} case $ext in pdf) xpdf "$dat" ;; sh) shellcheck "$dat" ;; png|jpg|gif) eog "$dat" ;; wav|mp3) aplay "$dat" ;; *) echo Unbekanntes Dateiformat"!" ;; esac 14.3.) Schleifen for-Schleife while-Schleife until-Schleife params="a b c" for z in $params do echo $z done #!/bin/bash # for-schleife for wort in Hallo "du Welt" "da draußen" do echo "$wort" done #!/bin/bash # Variablendefinition inputdir="/home/foo/Bilder/ZuBearbeiten" outputdir="/home/foo/Bilder/Bearbeitet" # Abarbeiten der eingelesenen Bilder mit Hilfe einer For-Schleife # und dem Programm ImageMagick. for pic in "$inputdir"/*.png do picname=$(basename "$pic") echo "Bearbeite Bild: $picname" convert "$pic" -colorspace Gray "$outputdir/$picname" done for wert in "${array[@]}" do Befehl... done for ((Anfangswert;Bedingung;Operation)) do Befehl1 Befehl2 # usw. done for ((z=2004;z<=2014;z++)) do mkdir Archiv_"$z" done while [ Test-Bedingung ] do Befehl1 Befehl2 # usw. done #!/bin/bash # Warten auf das richtige Ergebnis. echo "F rage: Was ergibt 2 + 2" echo "" while ((answer != 4)) do read -p "Bitte ihre Eingabe:" answer case "$answer" in 4) echo richtig ;; *) echo falsch ;; esac done Eine while-Schleife eignet sich auch besonders gut, um ohne Interaktion Datendateien abzuarbeiten. Hierzu ein weiteres Beispiel: #!/bin/bash # Liste aus einer .csv-Datei verarbeiten while read stapel do readarray -td\; zeile <<<"$stapel" echo " Vorname: ${zeile[0]} Name: ${zeile[1]} Funktion: ${zeile[2]}" done < liste.csv; echo 15.) Parameter an ein Skript übergeben #!/bin/bash # willkommen if [ $1 == "Pingu" ] then echo "Hallo, kleiner Pingu!" else echo "Hallo, $1" fi Die Variable $# gibt die Anzahl der verwendeten Parameter aus. So kann man prüfen, ob das Skript sinnvoll verwendet wird: #!/bin/bash # Willkommen if [ $# -ne 1 ] then echo; echo "Verwendung: $0 Name"; echo elif [ $1 == "Pingu" ] then echo "Hallo, kleiner Pingu!" else echo "Hallo, $1" fi 16.) Funktionen funktionsname(){ Befehle... } #!/bin/bash PFAD="/home/pingu/" # Funktionsdefinitionen wievieledateien() { anzahl=0 for file in "$PFAD"/* ; do (( anzahl++ )) done echo "Es befinden sich $anzahl Dateien und Ordner in $PFAD" } ./zaehledateien #!/bin/bash wievieledateien() { zaehlpfad="$1" for file in "$zaehlpfad"/* ; do (( anzahl++ )) done echo "Es befinden sich $anzahl Dateien und Ordner in $zaehlpfad" } wievieledateien /home/pingu wievieledateien /home/edit