Bash/Kontrollstrukturen: Unterschied zwischen den Versionen
Markierung: Zurückgesetzt |
|||
(35 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
'''Bash/Kontrollstrukturen''' - | '''Bash/Kontrollstrukturen''' - Verzweigungen, Schleifen, Fallunterscheidungen | ||
== Beschreibung == | == Beschreibung == | ||
Ablauf eines Linux-Shell-Skripts steuern | |||
== Bedingungen == | == Bedingungen == | ||
Zeile 12: | Zeile 12: | ||
* 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 | * 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 | * 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 ('>') | * 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 ('>') | ||
Zeile 21: | Zeile 20: | ||
; Syntax | ; Syntax | ||
<syntaxhighlight lang="bash" highlight="" line> | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if Bedingung1 | if Bedingung1 | ||
then Befehle1 | then Befehle1 | ||
Zeile 31: | Zeile 30: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
* Wenn die Bedingung1 erfüllt ist, werden die Befehle1 ausgeführt | * Wenn die Bedingung1 erfüllt ist, werden die Befehle1 ausgeführt | ||
* Bedingungen werden normalerweise mit dem Befehl test formuliert | ** 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 | ; Beispiele | ||
Man achte auf die Positionierung der Semikoli | Man achte auf die Positionierung der Semikoli | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
#!/bin/sh | #!/bin/sh | ||
# Füge eine 0 vor Zahlen kleiner 10 ein | # Füge eine 0 vor Zahlen kleiner 10 ein | ||
Zeile 45: | Zeile 48: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
#!/bin/bash | #!/bin/bash | ||
# Erstelle ein Verzeichnis, wenn es noch nicht existiert | # Erstelle ein Verzeichnis, wenn es noch nicht existiert | ||
Zeile 54: | Zeile 57: | ||
==== einseitiges if ==== | ==== einseitiges if ==== | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if kommandoliste | if kommandoliste | ||
then | then | ||
Zeile 62: | Zeile 65: | ||
==== zweiseitiges if ==== | ==== zweiseitiges if ==== | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if kommandoliste | if kommandoliste | ||
then | then | ||
Zeile 72: | Zeile 75: | ||
==== Mehrstufiges if ==== | ==== Mehrstufiges if ==== | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if kommandoliste1 | if kommandoliste1 | ||
then | then | ||
Zeile 86: | Zeile 89: | ||
=== Beispiele === | === Beispiele === | ||
Es soll eine Meldung ausgegeben werden, falls mehr als 5 Benutzer eingeloggt sind | Es soll eine Meldung ausgegeben werden, falls mehr als 5 Benutzer eingeloggt sind | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
USERS=`who | wc -l` # Zeilen der who-Ausgabe zählen | USERS=`who | wc -l` # Zeilen der who-Ausgabe zählen | ||
if | if test USERS -gt 5 | ||
then | then | ||
echo "Mehr als 5 Benutzer am Geraet" | echo "Mehr als 5 Benutzer am Geraet" | ||
Zeile 95: | Zeile 98: | ||
Kürzere Variante | Kürzere Variante | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if [(who | wc -l) -gt 5 ] ; then | if [(who | wc -l) -gt 5 ] ; then | ||
echo "Mehr als 5 Benutzer am Geraet" | echo "Mehr als 5 Benutzer am Geraet" | ||
Zeile 104: | Zeile 107: | ||
Ein weiteres Beispiel zeigt eine Fehlerprüfung | Ein weiteres Beispiel zeigt eine Fehlerprüfung | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
if test# -eq 0 | if test # -eq 0 | ||
then | then | ||
echo "usage: sortiere filename" >&2 | echo "usage: sortiere filename" >&2 | ||
Zeile 114: | Zeile 117: | ||
; Beispiel | ; 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 | * Fehlt der Parameter, wird interaktiv nachgefragt | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
if [# -eq 0 ] # falls keine Angabe | if [# -eq 0 ] # falls keine Angabe | ||
then # interaktiv erfragen | then # interaktiv erfragen | ||
Zeile 124: | Zeile 129: | ||
DATEI=$1 | DATEI=$1 | ||
fi | fi | ||
if [ - | if [ -f DATEI ] # wenn normale Datei | ||
then # dann ausgeben | then # dann ausgeben | ||
lessDATEI | lessDATEI | ||
elif [ - | elif [ -d DATEI ] # wenn aber Verzeichnis | ||
then # dann Dateien zeigen | then # dann Dateien zeigen | ||
ls - | ls -CF DATEI | ||
else # sonst Fehlermeldung | else # sonst Fehlermeldung | ||
echo "cannot showDATEI" | echo "cannot showDATEI" | ||
Zeile 137: | Zeile 142: | ||
; Beispiel | ; Beispiel | ||
Hängt eine Datei an eine andere Datei an; vorher erfolgt eine Prüfung der Zugriffsberechtigungen | Hängt eine Datei an eine andere Datei an; vorher erfolgt eine Prüfung der Zugriffsberechtigungen | ||
append Datei1 Datei2 | append Datei1 Datei2 | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
if [ - | if [ -r $1 -a -w $2 ] | ||
then | then | ||
cat $1 >> $2 | |||
else | else | ||
echo "cannot append" | echo "cannot append" | ||
Zeile 151: | Zeile 157: | ||
; Beispiel | ; Beispiel | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
if [ ! - | if [ ! -n $1 ] ; then | ||
echo "Kein Parameter" | echo "Kein Parameter" | ||
fi | fi | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Ist 1 wirklich nicht angegeben, wird das Kommando reduziert zu | |||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if [ ! -n ] ; then ... | if [ ! -n ] ; then ... | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Es ist also unvollständig und es erfolgt eine Fehlermeldung. Dagegen liefert | Es ist also unvollständig und es erfolgt eine Fehlermeldung. Dagegen liefert | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if [ ! -n "$1" ] ; then | if [ ! -n "$1" ] ; then | ||
echo "Kein Parameter" | echo "Kein Parameter" | ||
Zeile 170: | Zeile 176: | ||
bei fehlendem Parameter den korrekten Befehl | bei fehlendem Parameter den korrekten Befehl | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
if [ ! -n "" ] | if [ ! -n "" ] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Zeile 177: | Zeile 183: | ||
; Weiteres Beispiel | ; Weiteres Beispiel | ||
Es kommt | 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> | <syntaxhighlight lang="bash" highlight="" line="" copy="">#!/bin/sh | ||
#!/bin/sh | |||
# Change user-id | # Change user-id | ||
# | # | ||
Zeile 194: | Zeile 199: | ||
exit | exit | ||
fi | fi | ||
find / -group1 -exec chgrp2 {} ";" | find / -group1 -exec chgrp2 {} ";"</syntaxhighlight> | ||
</syntaxhighlight> | |||
== Fallunterscheidung == | == Fallunterscheidung == | ||
Zeile 219: | Zeile 223: | ||
; Beispiele | ; Beispiele | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
#!/bin/sh | #!/bin/sh | ||
# Mit dem ersten Argument in der Befehlszeile | # Mit dem ersten Argument in der Befehlszeile | ||
# wird die entsprechende Aktion festgelegt | # wird die entsprechende Aktion festgelegt | ||
case 1 in # nimmt das erste Argument | |||
Ja|Nein) response=1;; | Ja|Nein) response=1;; | ||
*) echo "Unbekannte Option"; exit 1;; | *) echo "Unbekannte Option"; exit 1;; | ||
Zeile 230: | Zeile 234: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
#!/bin/sh | #!/bin/sh | ||
# Lies die Zeilen von der Standardeingabe, bis eine | # Lies die Zeilen von der Standardeingabe, bis eine | ||
Zeile 249: | Zeile 253: | ||
Diese Anweisung erlaubt eine Mehrfachauswahl. Sie wird auch gerne deshalb verwendet, weil sie Muster mit Jokerzeichen und mehrere Muster für eine Auswahl erlauben | 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 | case selector in | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line> | ||
Muster-1) Kommandofolge 1 ;; | Muster-1) Kommandofolge 1 ;; | ||
Muster-2) Kommandofolge 2 ;; | Muster-2) Kommandofolge 2 ;; | ||
Zeile 262: | Zeile 266: | ||
* Vor der Klammer können mehrere Muster, getrennt durch <tt>| </tt>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=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
case selector in | case selector in | ||
Muster1) Kommandofolge1 ;; | Muster1) Kommandofolge1 ;; | ||
Zeile 273: | Zeile 277: | ||
; Beispiel 1 | ; Beispiel 1 | ||
Automatische Bearbeitung von Quell- und Objekt-Dateien. Der Aufruf erfolgt mit 'compile Datei' | Automatische Bearbeitung von Quell- und Objekt-Dateien. Der Aufruf erfolgt mit 'compile Datei' | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
case1 in | case1 in | ||
*.s) as1 ;; # Assembler aufrufen | *.s) as1 ;; # Assembler aufrufen | ||
Zeile 284: | Zeile 288: | ||
; Beispiel 2 | ; Beispiel 2 | ||
Menü mit interaktiver Eingabe | Menü mit interaktiver Eingabe | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
while : # Endlosschleife | while : # Endlosschleife | ||
do | do | ||
Zeile 297: | Zeile 301: | ||
echo "Eingabe: \c" # kein Zeilenvorschub | echo "Eingabe: \c" # kein Zeilenvorschub | ||
read ANTW | read ANTW | ||
case ANTW in | |||
0) kill -9 0 ;; # und tschuess | 0) kill -9 0 ;; # und tschuess | ||
1) date ;; | 1) date ;; | ||
Zeile 310: | Zeile 314: | ||
== Schleifen == | == Schleifen == | ||
; for-Anweisung | ; 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 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 | * In der Shell dagegen wird die Laufvariable nicht mit aufeinander folgenden Zahlen belegt, sondern mit einzelnen Werten aus einer anzugebenden Liste | ||
Zeile 317: | Zeile 324: | ||
Die Syntax der for-Schleife lautet wie folgt | Die Syntax der for-Schleife lautet wie folgt | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
for x [ in Liste ] | for x [ in Liste ] | ||
do | do | ||
Zeile 331: | Zeile 338: | ||
=== for-Schleife mit Liste === | === for-Schleife mit Liste === | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
for selector in liste | for selector in liste | ||
do | do | ||
Zeile 341: | Zeile 348: | ||
; Beispiele | ; Beispiele | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
for X in hans heinz karl luise do | for X in hans heinz karl luise do echo X done | ||
</syntaxhighlight> | |||
Ausgabe | Ausgabe | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line> | ||
hans | hans | ||
heinz | heinz | ||
Zeile 352: | Zeile 360: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
for FILE in *.txt # drucke alle Textdateien | for FILE in *.txt # drucke alle Textdateien | ||
do # im aktuellen Verzeichnis | do # im aktuellen Verzeichnis | ||
lpr FILE | |||
done | done | ||
for XX | for XX in VAR # geht auch mit | ||
do | do | ||
echo XX | |||
done | done | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Durchsuche Kapitel zur Erstellung einer Wortliste (wie fgrep -f) | Durchsuche Kapitel zur Erstellung einer Wortliste (wie fgrep -f) | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
for item in(cat program_list) # cat: Datei ausgeben | for item in (cat program_list) # cat: Datei ausgeben | ||
do | do | ||
echo "Pruefung der Kapitel auf" | echo "Pruefung der Kapitel auf" | ||
Zeile 372: | Zeile 380: | ||
done | done | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== for-Schleife mit Parametern === | === for-Schleife mit Parametern === | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
for selector | for selector | ||
do | do | ||
Zeile 386: | Zeile 393: | ||
; Beispiel | ; Beispiel | ||
Die Prozedur 'makebak' erzeugt für die in der Parameterliste angegebenen Dateien eine .bak-Datei | Die Prozedur 'makebak' erzeugt für die in der Parameterliste angegebenen Dateien eine .bak-Datei | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
for FF | for FF | ||
do | do | ||
Zeile 414: | Zeile 421: | ||
Die kopfgesteuerte Schleife. Die Syntax der while-Schleife lautet wie folgt | Die kopfgesteuerte Schleife. Die Syntax der while-Schleife lautet wie folgt | ||
<syntaxhighlight lang="bash" highlight=" | |||
<syntaxhighlight lang="bash" highlight="" line copy> | |||
while Bedingung | while Bedingung | ||
do | do | ||
Zeile 429: | Zeile 437: | ||
; Beispiele | ; Beispiele | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
#!/bin/sh | #!/bin/sh | ||
Zeile 436: | Zeile 444: | ||
while [ -n "$1"]; do | while [ -n "$1"]; do | ||
echo 1 | |||
shift # mit shift werden die Parameter nach | shift # mit shift werden die Parameter nach | ||
# Links geshiftet (aus2 wird1) | # Links geshiftet (aus2 wird1) | ||
Zeile 447: | Zeile 455: | ||
Da das mit der for-Schleife der Shell nicht geht, ersetzt man die Funktion durch geschickte Anwendung der while-Schleife | Da das mit der for-Schleife der Shell nicht geht, ersetzt man die Funktion durch geschickte Anwendung der while-Schleife | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line="" copy=""> | ||
#!/bin/sh | #!/bin/sh | ||
# Ausgabe der Zahlen von 1 bis 100 | # Ausgabe der Zahlen von 1 bis 100 | ||
i=1 | i=1 | ||
while [i -le 100 ] | while [ i -le 100 ] | ||
do | do | ||
echoi | echoi | ||
Zeile 457: | Zeile 465: | ||
done | done | ||
</syntaxhighlight> | </syntaxhighlight> | ||
; Weitere Beispiele | ; Weitere Beispiele | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
#!/bin/sh | #!/bin/sh | ||
Zeile 473: | Zeile 480: | ||
; Ergebniswert eines Kommandos | ; 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 | 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=" | |||
<syntaxhighlight lang="bash" highlight="" line="" copy=""> | |||
while Bedingung | while Bedingung | ||
do | do | ||
Kommandofolge | Kommandofolge | ||
done | done</syntaxhighlight> | ||
</syntaxhighlight> | |||
Solange der Bedingungsausdruck den Wert 'true' liefert, wird die Schleife ausgeführt | Solange der Bedingungsausdruck den Wert 'true' liefert, wird die Schleife ausgeführt | ||
; Warten auf eine Datei (beispielsweise vom Hintergrundprozess) | ; Warten auf eine Datei (beispielsweise vom Hintergrundprozess) | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
while [ ! -f foo ] | while [ ! -f foo ] | ||
do | do | ||
Zeile 500: | Zeile 507: | ||
; Umbenennen von Dateien durch Anhängen eines Suffix | ; Umbenennen von Dateien durch Anhängen eines Suffix | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
# Aufruf change suffix datei(en) | # Aufruf change suffix datei(en) | ||
if [# -lt 2 ] ; then | if [# -lt 2 ] ; then | ||
Zeile 515: | Zeile 520: | ||
done | done | ||
fi | fi | ||
</syntaxhighlight> | |||
; Umbenennen von Dateien durch Anhängen eines Suffix Variante 2 mit for | ; Umbenennen von Dateien durch Anhängen eines Suffix Variante 2 mit for | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
# Aufruf change suffix datei(en) | # Aufruf change suffix datei(en) | ||
if [# -lt 2 ] ; then | if [# -lt 2 ] ; then | ||
Zeile 536: | Zeile 542: | ||
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 | 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=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
until Bedingung | until Bedingung | ||
do | do | ||
Zeile 546: | Zeile 552: | ||
; Beispiel | ; Beispiel | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
# warten auf Datei foo | # warten auf Datei foo | ||
until [ -f foo ] | until [ -f foo ] | ||
Zeile 555: | Zeile 561: | ||
; Warten auf einen Benutzer | ; Warten auf einen Benutzer | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
# warten, bis sich der Benutzer hans eingeloggt hat | # warten, bis sich der Benutzer hans eingeloggt hat | ||
TT=`who | grep -c "hans"` | TT=`who | grep -c "hans"` | ||
Zeile 577: | Zeile 583: | ||
; Beispiel | ; Beispiel | ||
Hier wird die Bedingung nicht per test, sondern mit dem Rückgabewert des Programms grep formuliert | Hier wird die Bedingung nicht per test, sondern mit dem Rückgabewert des Programms grep formuliert | ||
<syntaxhighlight lang="bash" highlight=" | <syntaxhighlight lang="bash" highlight="" line copy> | ||
#!/bin/sh | #!/bin/sh | ||
# Warten, bis sich der Administrator einloggt | # Warten, bis sich der Administrator einloggt | ||
Zeile 590: | Zeile 596: | ||
[[Kategorie:Bash/Scripting]] | [[Kategorie:Bash/Scripting]] | ||
= TMP = | |||
=== Bedingte Ausführung === | |||
Die auch als '''Flusskontrolle '''bekannten Mechanismen ermöglichen eine kontrollierte Beeinflussung des Programmablaufs. Die Bash stellt die '''if...fi '''und '''case...esac '''-Konstrukte zur Verfügung. | |||
Erstere Form wird meist zur Unterscheidung einiger weniger Fälle (meist 2) verwendet. Die Syntax lautet: | |||
'''if '''Liste von Kommandos; '''then''' | |||
Liste von Kommandos | |||
'''[elif''' Liste von Kommandos; '''then''' | |||
Liste von Kommandos] | |||
'''[else''' | |||
Liste von Kommandos] | |||
'''fi''' | |||
Von den angegebenen Zweigen werden die Kommandos höchstens eines Zweiges ausgeführt. Entweder die des ersten Zweiges, dessen Bedingung erfüllt ist oder der optionale "else"-Zweig, falls keine Bedingung erfüllt wurde. | |||
Die Bedingung selbst ist der Rückgabewert der Liste der Kommandos (meist also der Rückgabewert des letzten Kommandos der Liste). | |||
Das "case"-Konstrukt wird bei einer höheren Anzahl an Auswahlkriterien bevorzugt. Prinzipiell kann mittels "case" jede "if"-Bedingung abgebildet werden. | |||
Ein wesentlicher Unterschied ist die mögliche Abarbeitung mehrerer Fälle, da alle Anweisungen ab der ersten zutreffenden Bedingung bis zu einem expliziten Verlassen des Konstrukts ausgeführt werden (d.h. ist eine Bedingung erfüllt, werden die nachfolgenden ignoriert). | |||
'''case''' Bedingung '''in''' | |||
Muster [ | Muster ]) | |||
Liste von Kommandos | |||
[;;] | |||
[Muster [ | Muster ]) | |||
Liste von Kommandos | |||
[;;]] | |||
'''esac''' | |||
Die Bedingung muss ein Token sein. Die Muster unterliegen denselben Expansionen wie Pfadnamen und dürfen somit Metazeichen enthalten. | |||
Stimmt ein Muster mit der Bedingung überein, werden alle nachfolgenden Kommandos bis zum Verlassen des Konstrukts mittels ";;" oder bis zum abschließenden "esac" ausgeführt. | |||
Der typische Anwendungsbereich für "if"- und "case"-Konstrukte ist die Shellprogrammierung und in diesem Zusammenhang werden Ihnen noch genügend Beispiele zur Benutzung begegnen. | |||
'''if test $(id | awk -F'[=(]' '{print $2}';) -eq "0"; then echo Superuser; else echo Normaler User; fi''' | |||
Normaler User | |||
'''su -''' | |||
Password: | |||
[mailto:root@lincln01 root@][mailto:root@lincln01 lincln01]> '''if test $(id | awk -F'[=(]' '{print $2}';) -eq "0"; then echo Superuser; else echo Normaler User; fi''' | |||
Superuser | |||
Das (zugegeben... etwas konstruierte) Beispiel entscheidet, ob der aufrufende Benutzer als Root oder als "normaler" Nutzer arbeitet. | |||
Die Verwendung des builtin-Kommandos '''test '''ist typisch für Bedingungen. | |||
[[Kategorie:Bash]] |
Aktuelle Version vom 11. Oktober 2025, 13:27 Uhr
Bash/Kontrollstrukturen - Verzweigungen, Schleifen, Fallunterscheidungen
Beschreibung
Ablauf eines Linux-Shell-Skripts steuern
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
if Bedingung1
then Befehle1
[ elif Bedingung2
then Befehle2 ]
..
[ else Befehle3 ]
fi
- 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
#!/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
#!/bin/bash
# Erstelle ein Verzeichnis, wenn es noch nicht existiert
dir=daten
if [ ! -edir ]; then
mkdirdir; fi # mkdir: Verzeichnis erstellen
einseitiges if
if kommandoliste
then
kommandos
fi
zweiseitiges if
if kommandoliste
then
kommandos
else
kommandos
fi
Mehrstufiges if
if kommandoliste1
then
kommandos
elif kommandoliste2
then
kommandos
elif ..
..
fi
Beispiele
Es soll eine Meldung ausgegeben werden, falls mehr als 5 Benutzer eingeloggt sind
USERS=`who | wc -l` # Zeilen der who-Ausgabe zählen
if test USERS -gt 5
then
echo "Mehr als 5 Benutzer am Geraet"
fi
Kürzere Variante
if [(who | wc -l) -gt 5 ] ; then
echo "Mehr als 5 Benutzer am Geraet"
fi
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
if test # -eq 0
then
echo "usage: sortiere filename" >&2
else
sort +1 -21 | lp
fi
- 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
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
- Beispiel
Hängt eine Datei an eine andere Datei an; vorher erfolgt eine Prüfung der Zugriffsberechtigungen
append Datei1 Datei2
if [ -r $1 -a -w $2 ]
then
cat $1 >> $2
else
echo "cannot append"
fi
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
if [ ! -n $1 ] ; then
echo "Kein Parameter"
fi
Ist 1 wirklich nicht angegeben, wird das Kommando reduziert zu
if [ ! -n ] ; then ...
Es ist also unvollständig und es erfolgt eine Fehlermeldung. Dagegen liefert
if [ ! -n "$1" ] ; then
echo "Kein Parameter"
fi
bei fehlendem Parameter den korrekten Befehl
if [ ! -n "" ]
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
#!/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 {} ";"
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
case Wert in
Muster1) Befehle1;;
Muster2) Befehle2;;
..
esac
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
#!/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
#!/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
- 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
Muster-1) Kommandofolge 1 ;;
Muster-2) Kommandofolge 2 ;;
...
Muster-n) Kommandofolge n ;;
esac
Die Variable selector (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 esac) 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 | stehen
- Das Zeichen | bildet eine Oder-Bedingung
case selector in
Muster1) Kommandofolge1 ;;
Muster2 | Muster3) Kommandofolge2 ;;
*) Kommandofolge3 ;;
esac
- Beispiel 1
Automatische Bearbeitung von Quell- und Objekt-Dateien. Der Aufruf erfolgt mit 'compile Datei'
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
- Beispiel 2
Menü mit interaktiver Eingabe
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
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
for x [ in Liste ]
do
Befehle
done
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
for selector in liste
do
Kommandofolge
done
Die Selektor-Variable wird nacheinander durch die Elemente der Liste ersetzt und die Schleife mit der Selektor-Variablen ausgeführt
- Beispiele
for X in hans heinz karl luise do echo X done
Ausgabe
hans
heinz
karl
luise
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
Durchsuche Kapitel zur Erstellung einer Wortliste (wie fgrep -f)
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
for-Schleife mit Parametern
for selector
do
Kommandofolge
done
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
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
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
while Bedingung
do
Befehle
done
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
#!/bin/sh
# Zeilenweise Ausgabe aller Aufrufparameter
while [ -n "$1"]; do
echo 1
shift # mit shift werden die Parameter nach
# Links geshiftet (aus2 wird1)
done
- 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
#!/bin/sh
# Ausgabe der Zahlen von 1 bis 100
i=1
while [ i -le 100 ]
do
echoi
i=`expri + 1`
done
- Weitere Beispiele
#!/bin/sh
while who | grep "^root "
do sleep 30
done
echo Die Katze ist aus dem Haus, Zeit, dass die Mäuse tanzen!
- Ergebniswert eines Kommandos
Als Bedingung kann nicht nur eine "klassische" Bedingung (test oder [ ]) sondern auch der Ergebniswert eines Kommandos oder einer Kommandofolge verwendet werden
while Bedingung
do
Kommandofolge
done
Solange der Bedingungsausdruck den Wert 'true' liefert, wird die Schleife ausgeführt
- Warten auf eine Datei (beispielsweise vom Hintergrundprozess)
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
- Umbenennen von Dateien durch Anhängen eines Suffix
# 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
- Umbenennen von Dateien durch Anhängen eines Suffix Variante 2 mit for
# 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
until
Diese Anweisung ist identisch zu einer while-Schleife mit negierter Bedingung
Als Bedingung kann nicht nur eine "klassische" Bedingung (test oder [ ]) sondern auch der Ergebniswert eines Kommandos oder einer Kommandofolge verwendet werden
until Bedingung
do
Kommandofolge
done
Die Schleife wird so lange abgearbeitet, bis Bedingungsausdruck einen Wert ungleich Null liefert
- Beispiel
# warten auf Datei foo
until [ -f foo ]
do
sleep 10
done
- Warten auf einen Benutzer
# 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
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
#!/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"
TMP
Bedingte Ausführung
Die auch als Flusskontrolle bekannten Mechanismen ermöglichen eine kontrollierte Beeinflussung des Programmablaufs. Die Bash stellt die if...fi und case...esac -Konstrukte zur Verfügung.
Erstere Form wird meist zur Unterscheidung einiger weniger Fälle (meist 2) verwendet. Die Syntax lautet:
if Liste von Kommandos; then Liste von Kommandos [elif Liste von Kommandos; then Liste von Kommandos] [else Liste von Kommandos] fi
Von den angegebenen Zweigen werden die Kommandos höchstens eines Zweiges ausgeführt. Entweder die des ersten Zweiges, dessen Bedingung erfüllt ist oder der optionale "else"-Zweig, falls keine Bedingung erfüllt wurde.
Die Bedingung selbst ist der Rückgabewert der Liste der Kommandos (meist also der Rückgabewert des letzten Kommandos der Liste).
Das "case"-Konstrukt wird bei einer höheren Anzahl an Auswahlkriterien bevorzugt. Prinzipiell kann mittels "case" jede "if"-Bedingung abgebildet werden.
Ein wesentlicher Unterschied ist die mögliche Abarbeitung mehrerer Fälle, da alle Anweisungen ab der ersten zutreffenden Bedingung bis zu einem expliziten Verlassen des Konstrukts ausgeführt werden (d.h. ist eine Bedingung erfüllt, werden die nachfolgenden ignoriert).
case Bedingung in Muster [ | Muster ]) Liste von Kommandos [;;] [Muster [ | Muster ]) Liste von Kommandos [;;]] esac
Die Bedingung muss ein Token sein. Die Muster unterliegen denselben Expansionen wie Pfadnamen und dürfen somit Metazeichen enthalten.
Stimmt ein Muster mit der Bedingung überein, werden alle nachfolgenden Kommandos bis zum Verlassen des Konstrukts mittels ";;" oder bis zum abschließenden "esac" ausgeführt.
Der typische Anwendungsbereich für "if"- und "case"-Konstrukte ist die Shellprogrammierung und in diesem Zusammenhang werden Ihnen noch genügend Beispiele zur Benutzung begegnen.
if test $(id | awk -F'[=(]' '{print $2}';) -eq "0"; then echo Superuser; else echo Normaler User; fi Normaler User su - Password: root@lincln01> if test $(id | awk -F'[=(]' '{print $2}';) -eq "0"; then echo Superuser; else echo Normaler User; fi Superuser
Das (zugegeben... etwas konstruierte) Beispiel entscheidet, ob der aufrufende Benutzer als Root oder als "normaler" Nutzer arbeitet.
Die Verwendung des builtin-Kommandos test ist typisch für Bedingungen.