|
|
(15 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) |
Zeile 1: |
Zeile 1: |
| '''Bash/Kontrollstrukturen''' - Ablauf eines Linux-Shell-Skripts steuern
| |
|
| |
| == Beschreibung ==
| |
| Bedingte Verzweigungen, Schleifen, Fallunterscheidungen
| |
|
| |
| == Bedingungen ==
| |
| === Bedingungen testen ===
| |
| siehe [[test]]
| |
|
| |
| === if - then - else ===
| |
| Als Bedingung kann nicht nur der test-Befehl, sondern eine beliebige Folge von Kommandos verwendet werden
| |
| * Jedes Kommando liefert einen Errorcode zurück, der bei erfolgreicher Ausführung gleich Null (true) und bei einem Fehler oder Abbruch ungleich Null (false) ist
| |
|
| |
| ; Testen einer Bedingung mit der if-Anweisung
| |
| Jede Anweisung muss entweder in einer eigenen Zeile stehen oder durch einen Strichpunkt von den anderen Anweisungen getrennt werden
| |
| * Trotzdem verhält sich eine bedingte Anweisung - oder die Schleifenkonstrukte, die weiter unten behandelt werden - wie eine einzige Anweisung
| |
| * Man kann dies ausprobieren, indem man eine if- oder while-Anweisung interaktiv eingibt. Solange nicht 'fi' bzw. 'done' eingetippt wurde, erhält man den PS2-Prompt ('>')
| |
|
| |
| Die if-Anweisung in der Shell-Programmierung macht das gleiche wie in allen anderen Programmiersprachen, sie testet eine Bedingung auf Wahrheit und macht davon den weiteren Ablauf des Programms abhängig
| |
|
| |
| ; Syntax
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if Bedingung1
| |
| then Befehle1
| |
| [ elif Bedingung2
| |
| then Befehle2 ]
| |
| ..
| |
| [ else Befehle3 ]
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| * Wenn die Bedingung1 erfüllt ist, werden die Befehle1 ausgeführt
| |
| ** andernfalls, wenn die Bedingung2 erfüllt ist, werden die Befehle2 ausgeführt.
| |
| * Trifft keine Bedingung zu, sollen die Befehle3 ausgeführt werden
| |
| * Bedingungen werden normalerweise mit dem Befehl test formuliert
| |
| * Es kann aber auch der Rückgabewert jedes anderen Kommandos ausgewertet werden
| |
| * Für Bedingungen, die auf jeden Fall zutreffen sollen steht der Null-Befehl (:) zur Verfügung
| |
|
| |
| ; Beispiele
| |
| Man achte auf die Positionierung der Semikoli
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| #!/bin/sh
| |
| # Füge eine 0 vor Zahlen kleiner 10 ein
| |
|
| |
| counter=0
| |
| if [counter -lt 10 ]; then
| |
| number=0$counter; else number=$counter; fi
| |
| </syntaxhighlight>
| |
|
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| #!/bin/bash
| |
| # Erstelle ein Verzeichnis, wenn es noch nicht existiert
| |
| dir=daten
| |
| if [ ! -edir ]; then
| |
| mkdirdir; fi # mkdir: Verzeichnis erstellen
| |
| </syntaxhighlight>
| |
|
| |
| ==== einseitiges if ====
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if kommandoliste
| |
| then
| |
| kommandos
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| ==== zweiseitiges if ====
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if kommandoliste
| |
| then
| |
| kommandos
| |
| else
| |
| kommandos
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| ==== Mehrstufiges if ====
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if kommandoliste1
| |
| then
| |
| kommandos
| |
| elif kommandoliste2
| |
| then
| |
| kommandos
| |
| elif ..
| |
| ..
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| === Beispiele ===
| |
| Es soll eine Meldung ausgegeben werden, falls mehr als 5 Benutzer eingeloggt sind
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| USERS=`who | wc -l` # Zeilen der who-Ausgabe zählen
| |
| if test USERS -gt 5
| |
| then
| |
| echo "Mehr als 5 Benutzer am Geraet"
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| Kürzere Variante
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if [(who | wc -l) -gt 5 ] ; then
| |
| echo "Mehr als 5 Benutzer am Geraet"
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| Man sollte bei der Entwicklung von Skripts aber ruhig mit der Langfassung beginnen und sich erst der Kurzfassung zuwenden, wenn man mehr Übung hat und die Langfassungen auf Anhieb funktionieren
| |
|
| |
| Ein weiteres Beispiel zeigt eine Fehlerprüfung
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| if test # -eq 0
| |
| then
| |
| echo "usage: sortiere filename" >&2
| |
| else
| |
| sort +1 -21 | lp
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| ; Beispiel
| |
| Zeigt eine mehr oder weniger intelligente Anzeige für Dateien und Verzeichnisse.
| |
|
| |
| 'show' zeigt bei Dateien den Inhalt mit 'less' an und Verzeichnisse werden mit 'ls' präsentiert
| |
| * Fehlt der Parameter, wird interaktiv nachgefragt
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| if [# -eq 0 ] # falls keine Angabe
| |
| then # interaktiv erfragen
| |
| echo -n "Bitte Namen eingeben: "
| |
| read DATEI
| |
| else
| |
| DATEI=$1
| |
| fi
| |
| if [ -f DATEI ] # wenn normale Datei
| |
| then # dann ausgeben
| |
| lessDATEI
| |
| elif [ -d DATEI ] # wenn aber Verzeichnis
| |
| then # dann Dateien zeigen
| |
| ls -CF DATEI
| |
| else # sonst Fehlermeldung
| |
| echo "cannot showDATEI"
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| ; Beispiel
| |
| Hängt eine Datei an eine andere Datei an; vorher erfolgt eine Prüfung der Zugriffsberechtigungen
| |
|
| |
| append Datei1 Datei2
| |
|
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| if [ -r $1 -a -w $2 ]
| |
| then
| |
| cat $1 >> $2
| |
| else
| |
| echo "cannot append"
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| Beim Vergleich von Zeichenketten sollten möglichst die Anführungszeichen (" ... ") verwendet werden, da sonst bei der Ersetzung durch die Shell unvollständige Test-Kommandos entstehen können
| |
|
| |
| ; Beispiel
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| if [ ! -n $1 ] ; then
| |
| echo "Kein Parameter"
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| Ist 1 wirklich nicht angegeben, wird das Kommando reduziert zu
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if [ ! -n ] ; then ...
| |
| </syntaxhighlight>
| |
|
| |
| Es ist also unvollständig und es erfolgt eine Fehlermeldung. Dagegen liefert
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if [ ! -n "$1" ] ; then
| |
| echo "Kein Parameter"
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| bei fehlendem Parameter den korrekten Befehl
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| if [ ! -n "" ]
| |
| </syntaxhighlight>
| |
|
| |
| Bei fehlenden Anführungszeichen werden auch führende Leerzeichen der Variablenwerte oder Parameter eliminiert
| |
|
| |
| ; Weiteres Beispiel
| |
| Es kommt vor, dass eine Userid wechselt oder die Gruppenzugehörigkeit von Dateien geändert werden muss. In solchen Fällen helfen die beiden folgenden Skripte
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">#!/bin/sh
| |
| # Change user-id
| |
| #
| |
| if [# -ne 2 ] ; then
| |
| echo "usage `basename0` <old id> <new id>"
| |
| exit
| |
| fi
| |
| find ~ -user1 -exec chown2 {} ";"
| |
| #!/bin/sh
| |
| # Change group-id
| |
| #
| |
| if [# -ne 2 ] ; then
| |
| echo "usage `basename0` <old id> <new id>"
| |
| exit
| |
| fi
| |
| find / -group1 -exec chgrp2 {} ";"</syntaxhighlight>
| |
|
| |
| == Fallunterscheidung ==
| |
| ; case
| |
| Auch die case-Anweisung ist vergleichbar in vielen anderen Sprachen vorhanden
| |
| * Sie dient, ähnlich wie die if-Anweisung, zur Fallunterscheidung. Allerdings wird hier nicht nur zwischen zwei Fällen unterschieden (Entweder / Oder), sondern es sind mehrere Fälle möglich
| |
| * Man kann die case-Anweisung auch durch eine geschachtelte if-Anweisung völlig umgehen, allerdings ist sie ein elegantes Mittel um den Code lesbar zu halten
| |
|
| |
| Die Syntax der case-Anweisung lautet wie folgt
| |
| <syntaxhighlight lang="bash" highlight="" line>
| |
| case Wert in
| |
| Muster1) Befehle1;;
| |
| Muster2) Befehle2;;
| |
| ..
| |
| esac
| |
| </syntaxhighlight>
| |
|
| |
| Wenn der Wert mit dem Muster1 übereinstimmt, wird die entsprechende Befehlsgruppe (Befehle1) ausgeführt, bei Übereinstimmung mit Muster2 werden die Kommandos der zweiten Befehlsgruppe (Befehle2) ausgeführt, und weitere
| |
| * Der letzte Befehl in jeder Gruppe muss mit ;; gekennzeichnet werden
| |
| * Das bedeutet für die Shell soviel wie springe zum nächsten esac, so dass die anderen Bedingungen nicht mehr überprüft werden
| |
| * In den Mustern sind die gleichen Meta-Zeichen erlaubt wie bei der Auswahl von Dateinamen
| |
| * Wenn in einer Zeile mehrere Muster angegeben werden sollen, müssen sie durch ein Pipezeichen (|, logisches ODER) getrennt werden
| |
|
| |
| ; Beispiele
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| #!/bin/sh
| |
| # Mit dem ersten Argument in der Befehlszeile
| |
| # wird die entsprechende Aktion festgelegt
| |
|
| |
| case 1 in # nimmt das erste Argument
| |
| Ja|Nein) response=1;;
| |
| *) echo "Unbekannte Option"; exit 1;;
| |
| esac
| |
| </syntaxhighlight>
| |
|
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| #!/bin/sh
| |
| # Lies die Zeilen von der Standardeingabe, bis eine
| |
| # Zeile mit einem einzelnen Punkt eingegeben wird
| |
| while : # Null-Befehl
| |
| do
| |
| echo -e "Zum Beenden . eingeben ==> \c"
| |
| read line # read: Zeile von StdIn einlesen
| |
| case "$line" in
| |
| .) echo "Ausgefuehrt"
| |
| break;;
| |
| *) echo "$line" >>./message ;;
| |
| esac
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| ; case-Anweisung
| |
| Diese Anweisung erlaubt eine Mehrfachauswahl. Sie wird auch gerne deshalb verwendet, weil sie Muster mit Jokerzeichen und mehrere Muster für eine Auswahl erlauben
| |
| case selector in
| |
| <syntaxhighlight lang="bash" highlight="" line>
| |
| Muster-1) Kommandofolge 1 ;;
| |
| Muster-2) Kommandofolge 2 ;;
| |
| ...
| |
|
| |
| Muster-n) Kommandofolge n ;;
| |
| esac
| |
| </syntaxhighlight>
| |
|
| |
| Die Variable <tt>selector</tt> (String) wird der Reihe nach mit den Mustern "Muster-1" bis "Muster-n" verglichen. Bei Gleichheit wird die nachfolgende Kommandofolge ausgeführt und dann nach der case-Anweisung (also hinter dem <tt>esac</tt>) fortgefahren. * In den Mustern sind Metazeichen (*, ?, []) erlaubt, im Selektor dagegen nicht
| |
| * Das Muster * deckt sich mit jedem Selektor --> default-Ausgang. muss als letztes Muster in der case-Konstruktion stehen
| |
| * Vor der Klammer können mehrere Muster, getrennt durch <tt>| </tt>stehen
| |
|
| |
| ; Das Zeichen <tt>| </tt>bildet eine Oder-Bedingung
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| case selector in
| |
| Muster1) Kommandofolge1 ;;
| |
| Muster2 | Muster3) Kommandofolge2 ;;
| |
| *) Kommandofolge3 ;;
| |
| esac
| |
| </syntaxhighlight>
| |
|
| |
| ; Beispiel 1
| |
| Automatische Bearbeitung von Quell- und Objekt-Dateien. Der Aufruf erfolgt mit 'compile Datei'
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| case1 in
| |
| *.s) as1 ;; # Assembler aufrufen
| |
| *.c) cc -c1 ;; # C-Compiler aufrufen
| |
| *.o) cc1 -o prog ;; # C-Compiler als Linker
| |
| *) echo "invalid parameter:1";;
| |
| esac
| |
| </syntaxhighlight>
| |
|
| |
| ; Beispiel 2
| |
| Menü mit interaktiver Eingabe
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| while : # Endlosschleife
| |
| do
| |
| tput clear # Schirm löschen und Menütext ausgeben
| |
| echo " +---------------------------------+"
| |
| echo " | 0 --> Ende |"
| |
| echo " | 1 --> Datum und Uhrzeit |"
| |
| echo " | 2 --> aktuelles Verzeichnis |"
| |
| echo " | 3 --> Inhaltsverzeichnis |"
| |
| echo " | 4 --> Mail |"
| |
| echo "+----------------------------------+"
| |
| echo "Eingabe: \c" # kein Zeilenvorschub
| |
| read ANTW
| |
| case ANTW in
| |
| 0) kill -9 0 ;; # und tschuess
| |
| 1) date ;;
| |
| 2) pwd ;;
| |
| 3) ls -CF ;;
| |
| 4) elm ;;
| |
| *) echo "Falsche Eingabe!" ;;
| |
| esac
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| == Schleifen ==
| |
| ; for-Anweisung
| |
| Diese Schleifenanweisung hat zwei Ausprägungen
| |
| * mit einer Liste der zu bearbeitenden Elemente
| |
| * mit den Kommandozeilenparametern
| |
|
| |
| Dieses Konstrukt ähnelt nur auf den ersten Blick seinen Pendants aus anderen Programmiersprachen
| |
| * In anderen Sprachen wird die for-Schleife meistens dazu benutzt, eine Zählvariable über einen bestimmten Wertebereich iterieren zu lassen (for i = 1 to 100...next)
| |
| * In der Shell dagegen wird die Laufvariable nicht mit aufeinander folgenden Zahlen belegt, sondern mit einzelnen Werten aus einer anzugebenden Liste
| |
| * Wenn man eine Laufvariable benötigt, muss man dazu die while-Schleife einsetzen
| |
|
| |
| Die Syntax der for-Schleife lautet wie folgt
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| for x [ in Liste ]
| |
| do
| |
|
| |
| Befehle
| |
|
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Die Befehle werden ausgeführt, wobei der Variablen x nacheinander die Werte aus der Liste zugewiesen werden
| |
| * Wie man sieht, ist die Angabe der Liste optional, wenn sie nicht angegeben wird, nimmt x der Reihe nach alle Werte aus@ (in dieser vordefinierten Variablen liegen die Aufrufparameter) an
| |
| * Wenn die Ausführung eines Schleifendurchlaufs bzw. der ganzen Schleife abgebrochen werden soll, müssen die Kommandos continue bzw. break benutzt werden
| |
|
| |
| === for-Schleife mit Liste ===
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| for selector in liste
| |
| do
| |
| Kommandofolge
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Die Selektor-Variable wird nacheinander durch die Elemente der Liste ersetzt und die Schleife mit der Selektor-Variablen ausgeführt
| |
|
| |
| ; Beispiele
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| for X in hans heinz karl luise do echo X done
| |
| </syntaxhighlight>
| |
|
| |
| Ausgabe
| |
| <syntaxhighlight lang="bash" highlight="" line>
| |
| hans
| |
| heinz
| |
| karl
| |
| luise
| |
| </syntaxhighlight>
| |
|
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| for FILE in *.txt # drucke alle Textdateien
| |
| do # im aktuellen Verzeichnis
| |
| lpr FILE
| |
| done
| |
| for XX in VAR # geht auch mit
| |
| do
| |
| echo XX
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Durchsuche Kapitel zur Erstellung einer Wortliste (wie fgrep -f)
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| for item in (cat program_list) # cat: Datei ausgeben
| |
| do
| |
| echo "Pruefung der Kapitel auf"
| |
| echo "Referenzen zum Programmitem ..."
| |
| grep -c "$item.[co]" chap* # grep: nach Muster suchen
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| === for-Schleife mit Parametern ===
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| for selector
| |
| do
| |
| Kommandofolge
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Die Selektor-Variable wird nacheinander durch die Parameter1 bisn ersetzt und mit diesen Werten die Schleife durchlaufen. Es gibt also# Schleifendurchläufe
| |
|
| |
| ; Beispiel
| |
| Die Prozedur 'makebak' erzeugt für die in der Parameterliste angegebenen Dateien eine .bak-Datei
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| for FF
| |
| do
| |
| cpFF{FF}.bak
| |
| done
| |
| #!/bin/sh
| |
| # Seitenweises Formatieren der Dateien, die auf der
| |
| # Befehlszeile angegeben wurden, und speichern des
| |
| # jeweiligen Ergebnisses
| |
|
| |
| for file do
| |
| prfile >file.tmp # pr: Formatiert Textdateien
| |
| done
| |
| # Ermittle einen Ein-Wort-Titel aus jeder Datei und
| |
| # verwende ihn als neuen Dateinamen
| |
|
| |
| for file do
| |
| name=`sed -n 's/NAME: //p'file`
| |
| # sed: Skriptsprache zur Textformatierung
| |
| mvfilename
| |
| # mv: Datei verschieben bzw. umbenennen
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| === while ===
| |
| Die while-Schleife ist wieder ein Konstrukt, das einem aus vielen anderen Sprachen bekannt ist
| |
|
| |
| Die kopfgesteuerte Schleife. Die Syntax der while-Schleife lautet wie folgt
| |
|
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| while Bedingung
| |
| do
| |
|
| |
| Befehle
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Die Befehle werden so lange ausgeführt, wie die Bedingung erfüllt ist
| |
|
| |
| Dabei wird die Bedingung vor der Ausführung der Befehle überprüft. Die Bedingung wird dabei üblicherweise, genau wie bei der if-Anweisung, mit dem Befehl test formuliert
| |
|
| |
| Wenn die Ausführung eines Schleifendurchlaufs bzw. der ganzen Schleife abgebrochen werden soll, müssen die Kommandos continue bzw. break benutzt werden
| |
|
| |
| ; Beispiele
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
|
| |
| #!/bin/sh
| |
| # Zeilenweise Ausgabe aller Aufrufparameter
| |
|
| |
| while [ -n "$1"]; do
| |
|
| |
| echo 1
| |
| shift # mit shift werden die Parameter nach
| |
| # Links geshiftet (aus2 wird1)
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
|
| |
| ; Zählschleife
| |
| In anderen Sprachen kann man mit der for-Schleife eine Zählvariable über einen bestimmten Wertebereich iterieren lassen (for i = 1 to 100...next)
| |
|
| |
| Da das mit der for-Schleife der Shell nicht geht, ersetzt man die Funktion durch geschickte Anwendung der while-Schleife
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| #!/bin/sh
| |
| # Ausgabe der Zahlen von 1 bis 100
| |
| i=1
| |
| while [ i -le 100 ]
| |
| do
| |
| echoi
| |
| i=`expri + 1`
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| ; Weitere Beispiele
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| #!/bin/sh
| |
|
| |
| while who | grep "^root "
| |
| do sleep 30
| |
|
| |
| done
| |
|
| |
| echo Die Katze ist aus dem Haus, Zeit, dass die Mäuse tanzen!
| |
| </syntaxhighlight>
| |
|
| |
| ; Ergebniswert eines Kommandos
| |
| Als Bedingung kann nicht nur eine "klassische" Bedingung (<tt>test</tt> oder <tt>[ ]</tt>) sondern auch der Ergebniswert eines Kommandos oder einer Kommandofolge verwendet werden
| |
|
| |
| <syntaxhighlight lang="bash" highlight="" line="" copy="">
| |
| while Bedingung
| |
| do
| |
| Kommandofolge
| |
| done</syntaxhighlight>
| |
|
| |
| Solange der Bedingungsausdruck den Wert 'true' liefert, wird die Schleife ausgeführt
| |
|
| |
| ; Warten auf eine Datei (beispielsweise vom Hintergrundprozess)
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| while [ ! -f foo ]
| |
| do
| |
| sleep 10 # Wichtig damit die Prozesslast nicht zu hoch wird
| |
| done
| |
|
| |
| ; Pausenfüller für das Terminal Abbruch mit DEL-Taste
| |
| while
| |
| do
| |
| tput clear # BS löschen
| |
| echo -e "\n\n\n\n\n" # 5 Leerzeilen
| |
| banner(date '+ %T ') # Uhrzeit groß
| |
| sleep 10 # 10s Pause
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| ; Umbenennen von Dateien durch Anhängen eines Suffix
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| # Aufruf change suffix datei(en)
| |
| if [# -lt 2 ] ; then
| |
| echo "Usage: `basename0` suffix file(s)"
| |
| else
| |
| SUFF=$1 # Suffix speichern
| |
| shift
| |
| while [# -ne 0 ] # solange Parameter da sind
| |
| do
| |
| mv1{1}.$SUFF # umbenennen
| |
| shift
| |
| done
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| ; Umbenennen von Dateien durch Anhängen eines Suffix Variante 2 mit for
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| # Aufruf change suffix datei(en)
| |
| if [# -lt 2 ] ; then
| |
| echo "Usage: `basename0` suffix file(s)"
| |
| else
| |
| SUFF=$1 # Suffix speichern
| |
| shift
| |
| for FILE
| |
| do
| |
| mvFILE{FILE}.$SUFF # umbenennen
| |
| shift
| |
| done
| |
| fi
| |
| </syntaxhighlight>
| |
|
| |
| === until ===
| |
| Diese Anweisung ist identisch zu einer <tt>while</tt>-Schleife mit negierter Bedingung
| |
|
| |
| Als Bedingung kann nicht nur eine "klassische" Bedingung (<tt>test</tt> oder <tt>[ ]</tt>) sondern auch der Ergebniswert eines Kommandos oder einer Kommandofolge verwendet werden
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| until Bedingung
| |
| do
| |
| Kommandofolge
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Die Schleife wird so lange abgearbeitet, bis Bedingungsausdruck einen Wert ungleich Null liefert
| |
|
| |
| ; Beispiel
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| # warten auf Datei foo
| |
| until [ -f foo ]
| |
| do
| |
| sleep 10
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| ; Warten auf einen Benutzer
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| # warten, bis sich der Benutzer hans eingeloggt hat
| |
| TT=`who | grep -c "hans"`
| |
| until [TT -gt 0 ]
| |
| do
| |
| sleep 10
| |
| TT=`who | grep -c "hans"`
| |
| done
| |
| # warten, bis sich der Benutzer hans eingeloggt hat
| |
| # Variante 2 - kuerzer
| |
| until [ `who | grep -c "hans"` -gt 0 ]
| |
| do
| |
| sleep 10
| |
| done
| |
| </syntaxhighlight>
| |
|
| |
| Die Befehle werden ausgeführt, bis die Bedingung erfüllt ist. Die Bedingung wird dabei üblicherweise, genau wie bei der if-Anweisung, mit dem Befehl test formuliert
| |
|
| |
| Wenn die Ausführung eines Schleifendurchlaufs bzw. der ganzen Schleife abgebrochen werden soll, müssen die Kommandos continue bzw. break benutzt werden
| |
|
| |
| ; Beispiel
| |
| Hier wird die Bedingung nicht per test, sondern mit dem Rückgabewert des Programms grep formuliert
| |
| <syntaxhighlight lang="bash" highlight="" line copy>
| |
| #!/bin/sh
| |
| # Warten, bis sich der Administrator einloggt
| |
|
| |
| until who | grep "root"; do
| |
| # who: Liste der Benutzer
| |
| # grep: Suchen nach Muster
| |
| sleep 30 # sleep: warten
| |
| done
| |
| echo "Der Meister ist anwesend"
| |
| </syntaxhighlight>
| |
|
| |
|
| [[Kategorie:Bash/Scripting]] | | [[Kategorie:Bash/Scripting]] |