Zum Inhalt springen

Kategorie:Bash/Kontrollstrukturen: Unterschied zwischen den Versionen

Aus Foxwiki
Die Seite wurde neu angelegt: „= {{anchor|RefHeadingToc25752005955943}} Kontrollstrukturen = Bei der Shell-Programmierung verfügt man über ähnliche Konstrukte wie bei anderen Programmier…“
 
Der Seiteninhalt wurde durch einen anderen Text ersetzt: „ Kategorie:Bash/Scripting
Markierung: Ersetzt
 
(109 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
= {{anchor|RefHeadingToc25752005955943}} Kontrollstrukturen =


Bei der Shell-Programmierung verfügt man über ähnliche Konstrukte wie bei anderen Programmiersprachen, um den Ablauf des Programms zu steuern. Dazu gehören bedingte Verzweigungen, Schleifen und Fallunterscheidungen.
[[Kategorie:Bash/Scripting]]
 
== Bedingungen testen ==
 
Das wichtigste Kommando ist 'test', mit dem man mannigfache Bedingungen testen kann.
 
<div style="margin-left:0cm;margin-right:0cm;">test Argument </div>
 
Dieses Kommando prüft eine Bedingung und liefert 'true' (0), falls die Bedingung erfüllt ist und 'false' (1), falls die Bedingung nicht erfüllt ist. Der Fehlerwert 2 wird zurückgegeben, wenn das Argument syntaktisch falsch ist (meist durch Ersetzung hervorgerufen).
 
Es lassen sich Dateien, Zeichenketten und Integer-Zahlen (16 Bit, bei Linux 32 Bit) überprüfen. Das Argument von Test besteht aus einer Testoption und einem Operanden, der ein Dateiname oder eine Shell-Variable (Inhalt: String oder Zahl) sein kann.
 
In bestimmten Fällen können auf der rechten Seite eines Vergleichs auch Strings oder Zahlen stehen - bei der Ersetzung von leeren Variablen kann es aber zu Syntaxfehlern kommen. Weiterhin lassen sich mehrere Argumente logisch verknüpfen (UND, ODER, NICHT). Beispiel:
 
<div style="margin-left:0cm;margin-right:0cm;">test -w /etc/passwd </div>
 
mit der Kommandoverkettung lassen sich so schon logische Entscheidungen treffen, z. B.:
 
<div style="margin-left:0cm;margin-right:0cm;">test -w /etc/passwd && echo "Du bist ROOT" </div>
 
Normalerweise kann statt 'test' das Argument auch in eckigen Klammern gesetzt werden. Die Klammern müssen von Leerzeichen umschlossen werden:
 
<div style="margin-left:0cm;margin-right:0cm;">[ -w /etc/passwd ] </div>
 
Die folgenden Operationen können bei 'test' bzw. [ ... ] verwendet werden.
 
 
{| align="center" style="border-spacing:0;width:17.501cm;"
|- style="border-top:2.5pt solid #000000;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;"
| colspan="2" | '''Dateitests: '''
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-b Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist ein blockorientiertes Gerät
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-c Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist ein zeichenorientiertes Gerät
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-d Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist ein Verzeichnis
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-e Datei'''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Datei existiert
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-f Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist eine reguläre Datei
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-g Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und das Gruppen-ID-Bit ist gesetzt
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-h Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist ein symbolischer Link
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-k Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und das Sticky-Bit ist gesetzt
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-p Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist eine Named Pipe
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-r Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist lesbar
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-s Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist nicht leer
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-t [n] '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | DATEI-Descriptor FD (Standard: Standardausgabe) ist auf Tty offen
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-u Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und das Setuid-Bit ist gesetzt
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-w Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist beschreibbar
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-x Datei '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Datei existiert und ist ausführbar
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Datei1 -nt Datei2
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Datei1 ist neuer als Datei2
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Datei1 -ot Datei2
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Datei1 ist älter als Datei2
|-
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Datei1 -ef Datei2
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Beide Dateien belegen dieselbe Inode auf demselben Gerät
|-
|}
'''Beispiel'''
 
<div style="margin-left:0cm;margin-right:0cm;">if [ -d RCS ]    Wenn ein Verzeichnis RCS existiert. . .</div>
 
 
{| align="center" style="border-spacing:0;width:17.501cm;"
|- style="border-top:2.5pt solid #000000;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;"
| colspan="2" | '''Bedingungen für Zeichenfolgen: '''
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-n s1 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Länge der Zeichenfolge s1 ist ungleich Null
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''-z s1 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Länge der Zeichenfolge s1 ist gleich Null
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''s1 = s2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Zeichenfolgen s1 und s2 sind identisch
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''s1 != s2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Zeichenfolgen s1 und s2 sind nicht identisch
|-
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''Zeichenfolge '''</tt>
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Die Zeichenfolge ist nicht Null
|-
|}
'''Beispiel'''
 
<div style="margin-left:0cm;margin-right:0cm;">if [ "$Antwort" != "j" ]    Wenn die $Antwort nicht "j" ist. . .</div>
 
 
 
{| align="center" style="border-spacing:0;width:17.501cm;"
|- style="border-top:2.5pt solid #000000;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;"
| colspan="2" | '''Ganzzahlvergleiche: '''
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''n1 -eq n2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | n1 ist gleich n2
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''n1 -ge n2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | n1 ist größer oder gleich n2
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''n1 -gt n2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | n1 ist größer als n2
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''n1 -le n2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | n1 ist kleiner oder gleich n2
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''n1 -lt n2 '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | n1 ist kleiner n2
|-
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''n1 -ne n2 '''</tt>
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | n1 ist ungleich n2
|-
|}
'''Beispiele'''
 
<div style="margin-left:0cm;margin-right:0cm;">while test $# -gt 0    Solange Argumente vorliegen. . .
while [ -n "$1" ]    Solange das erste Argument nicht leer ist. . .
if [ $count -lt 10 ]    Wenn $count kleiner 10. . .</div>
 
 
{| align="center" style="border-spacing:0;width:17.501cm;"
|- style="border-top:2.5pt solid #000000;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;"
| colspan="2" | '''Kombinierte Formen: '''
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''(Bedingung) '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Wahr, wenn die Bedingung zutrifft (wird für die Gruppierung verwendet). Den Klammern muss ein \ vorangestellt werden.
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''! Bedingung i '''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Wahr, wenn die Bedingung nicht zutrifft (NOT).
|-
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''Bedingung1 -a Bedingung2'''</tt>
| style="border-top:none;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Wahr, wenn beide Bedingungen zutreffen (AND).
|-
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:2.5pt solid #000000;border-right:none;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | <tt>'''Bedingung1 -o Bedingung2'''</tt>
| style="border-top:none;border-bottom:2.5pt solid #000000;border-left:0.5pt solid #000000;border-right:2.5pt solid #000000;padding-top:0.049cm;padding-bottom:0.049cm;padding-left:0.3cm;padding-right:0.3cm;" | Wahr, wenn eine der beiden Bedingungen zutrifft (OR).
|-
|}
'''Beispiel'''
 
<div style="margin-left:0cm;margin-right:0cm;">if [ ! -r "$1" -o ! -f "$1" ]    Wenn das erste Argument keine lesbare oder reguläre Datei ist.</div>
 
== Bedingte Anweisung (if - then - else) ==
 
Wichtig: Als Bedingung kann nicht nur der test-Befehl, sondern eine beliebige Folge von Kommados 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.
 
Zum Testen einer Bedingung dient die if-Anweisung.
 
Jede Anweisung muss entweder in einer eigenen Zeile stehen oder durch einen Strichpunkt von den anderen Anweisungen getrennt werden.
 
Trotzdem verhät sich eine bedingte Anweisung - oder die Schleifenkonstrukte, die weiter unten behandelt werden - wie eine einzige Anweisung.
 
Somit ergibt sich eine starke Ähnlichkeit mit der Blockstruktur von C oder Pascal.
 
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 ('>').
 
=== if ===
 
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.
 
Die Syntax der if-Anweisung lautet wie folgt:
 
<div style="margin-left:0cm;margin-right:0cm;">if Bedingung1
    then Befehle1
[ elif Bedingung2
    then Befehle2 ]
...
[ else Befehle3 ]
fi</div>
 
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.
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Füge eine 0 vor Zahlen kleiner 10 ein:</nowiki>
counter=0
if [ $counter -lt 10 ]; then
number=0$counter; else number=$counter; fi</div>
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/bash</nowiki>
<nowiki># Erstelle ein Verzeichnis, wenn es noch nicht existiert:</nowiki>
dir=daten
if [ ! -e $dir ]; then
mkdir $dir; fi # mkdir: Verzeichnis erstellen</div>
 
=== einseitiges if ===
 
<div style="margin-left:0cm;margin-right:0cm;">if kommandoliste
then
      kommandos
fi </div>
 
=== zweiseitiges if ===
 
<div style="margin-left:0cm;margin-right:0cm;">if kommandoliste
then
      kommandos
else
      kommandos
fi </div>
 
=== Mehrstufiges if ===
 
<div style="margin-left:0cm;margin-right:0cm;">if kommandoliste1
then
      kommandos
elif kommandoliste2
  then
        kommandos
elif ...
          ...
fi </div>
 
=== Beispiele ===
 
<u>Es soll eine Meldung ausgegeben werden, falls mehr als 5 Benutzer eingeloggt sind: </u>
 
<div style="margin-left:0cm;margin-right:0cm;">USERS=`who | wc -l`  <nowiki># Zeilen der who-Ausgabe zählen</nowiki>
if test $USERS -gt 5
then
  echo "Mehr als 5 Benutzer am Geraet"
fi </div>
 
<u>Das geht natürlich auch kürzer und ohne Backtics: </u>
 
<div style="margin-left:0cm;margin-right:0cm;">if [ $(who | wc -l) -gt 5 ] ; then
  echo "Mehr als 5 Benutzer am Geraet"
fi </div>
 
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.
 
<u>Ein weiteres Beispiel zeigt eine Fehlerprüfung: </u>
 
<div style="margin-left:0cm;margin-right:0cm;">if test $# -eq 0
then
  echo "usage: sortiere filename" >&2
else
  sort +1 -2 $1 | lp
fi </div>
 
Das nächste 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.
 
<u>Fehlt der Parameter, wird interaktiv nachgefragt: </u>
 
<div style="margin-left:0cm;margin-right:0cm;">if [ $# -eq 0 ]                          <nowiki># falls keine Angabe </nowiki>
then                                    <nowiki># interaktiv erfragen </nowiki>
    echo -n "Bitte Namen eingeben: "
    read DATEI
else 
    DATEI=$1
fi
if  [ -f $DATEI ]                        <nowiki># wenn normale Datei </nowiki>
then                                    <nowiki># dann ausgeben </nowiki>
    less $DATEI 
elif [ -d $DATEI ]                      <nowiki># wenn aber Verzeichnis </nowiki>
  then                                  <nowiki># dann Dateien zeigen </nowiki>
      ls -CF $DATEI
    else                                  <nowiki># sonst Fehlermeldung </nowiki>
      echo "cannot show $DATEI" 
fi</div>
 
Das nächste Beispiel hängt eine Datei an eine andere Datei an; vorher erfolgt eine Prüfung der Zugriffsberechtigungen:
 
<tt>append Datei1 Datei2</tt>
 
<div style="margin-left:0cm;margin-right:0cm;">if [ -r $1 -a -w $2 ]
then
    cat $1 >> $2
else
    echo "cannot append"
fi </div>
 
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.
 
Dazu ein Beispiel:
 
<div style="margin-left:0cm;margin-right:0cm;">if [ ! -n $1 ] ; then
    echo "Kein Parameter"
fi </div>
 
Ist $1 wirklich nicht angegeben, wird das Kommando reduziert zu:
 
<div style="margin-left:0cm;margin-right:0cm;">if [ ! -n ] ; then .... </div>
 
Es ist also unvollständig und es erfolgt eine Fehlermeldung. Dagegen liefert
 
<div style="margin-left:0cm;margin-right:0cm;">if [ ! -n "$1" ] ; then
    echo "Kein Parameter"
fi </div>
 
bei fehlendem Parameter den korrekten Befehl
 
<div style="margin-left:0cm;margin-right:0cm;">if [ ! -n "" ] </div>
 
Bei fehlenden Anführungszeichen werden auch führende Leerzeichen der Variablenwerte oder Parameter eliminiert.
 
<u>Noch ein Beispiel</u>
 
Es kommt ab und zu vor, dass eine Userid wechselt oder dass die Gruppenzugehörigkeit von Dateien geändert werden muss. In solchen fällen helfen die beiden folgenden Skripts:
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Change user-id</nowiki>
<nowiki>#</nowiki>
if [ $# -ne 2 ] ; then
  echo "usage `basename $0` <old id> <new id>"
  exit
fi
find ~ -user $1 -exec chown $2 {} ";"</div>
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Change group-id</nowiki>
<nowiki>#</nowiki>
if [ $# -ne 2 ] ; then
  echo "usage `basename $0` <old id> <new id>"
  exit
fi
find / -group $1 -exec chgrp $2 {} ";"</div>
 
== 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:
 
<div style="margin-left:0cm;margin-right:0cm;">case Wert in
    Muster1) Befehle1;;
    Muster2) Befehle2;;
...
esac</div>
 
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, usw.
 
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'''
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Mit dem ersten Argument in der Befehlszeile </nowiki>
<nowiki># wird die entsprechende Aktion festgelegt:</nowiki>
case $1 in # nimmt das erste Argument
      Ja|Nein) response=1;;
            <nowiki>*) echo "Unbekannte Option"; exit 1;;</nowiki>
esac</div>
 
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Lies die Zeilen von der Standardeingabe, bis eine</nowiki>
<nowiki># Zeile mit einem einzelnen Punkt eingegeben wird:</nowiki>
while : # Null-Befehl
do
    echo -e "Zum Beenden . eingeben ==> \c"
    read line # read: Zeile von StdIn einlesen
    case "$line" in
          .) echo "Ausgefuehrt"
            break;;
          <nowiki>*) echo "$line" >>./message ;;</nowiki>
    esac
done</div>
 
'''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
 
<div style="margin-left:0cm;margin-right:0cm;">case selector in
      Muster-1) Kommandofolge 1 ;;
      Muster-2) Kommandofolge 2 ;;
              ....
      Muster-n) Kommandofolge n ;;
esac </div>
 
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:
 
<div style="margin-left:0cm;margin-right:0cm;">case selector in
      Muster1)              Kommandofolge1 ;;
      Muster2 | Muster3)    Kommandofolge2 ;;
      <nowiki>*) </nowiki>                  Kommandofolge3 ;;
esac</div><u>Beispiel 1: Automatische Bearbeitung von Quell- und Objekt-Dateien. Der Aufruf erfolgt mit 'compile Datei'. </u>
 
<div style="margin-left:0cm;margin-right:0cm;">case $1 in
    <nowiki>*.s) as $1 ;; </nowiki>                      <nowiki># Assembler aufrufen </nowiki>
    <nowiki>*.c) cc -c $1 ;; </nowiki>                  <nowiki># C-Compiler aufrufen </nowiki>
    <nowiki>*.o) cc $1 -o prog ;; </nowiki>              <nowiki># C-Compiler als Linker </nowiki>
      <nowiki>*) echo "invalid parameter: $1";; </nowiki>
esac</div>
 
<u>Beispiel 2: Menü mit interaktiver Eingabe</u>
 
<div style="margin-left:0cm;margin-right:0cm;">while :  <nowiki># Endlosschleife (s. später) </nowiki>
do
tput clear  <nowiki># Schirm löschen und Menütext ausgeben </nowiki>
    echo " +---------------------------------+" 
    echo " | 0 --> Ende                      |"
    echo " | 1 --> Datum und Uhrzeit        |"
    echo " | 2 --> aktuelles Verzeichnis    |"
    echo " | 3 --> Inhaltsverzeichnis        |"
    echo " | 4 --> Mail                      |"
    echo "+----------------------------------+"
    echo "Eingabe: \c"  <nowiki># kein Zeilenvorschub </nowiki>
    read ANTW
    case $ANTW in
    0) kill -9 0 ;; # und tschuess
    1) date ;; 
    2) pwd ;;
    3) ls -CF ;;
    4) elm ;;
    <nowiki>*) echo "Falsche Eingabe!" ;; </nowiki>
    esac
done</div>
 
== for-Anweisung ==
 
Diese Schleifenanweisung hat zwei Ausprägungen, mit einer Liste der zu bearbeitenden Elemente oder 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:
 
<div style="margin-left:0cm;margin-right:0cm;">for x [ in Liste ]  
do
Befehle
done</div>
 
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 ===
 
<div style="margin-left:0cm;margin-right:0cm;">for selector in liste
  do
  Kommandofolge
done </div>
 
Die Selektor-Variable wird nacheinander durch die Elemente der Liste ersetzt und die Schleife mit der Selektor-Variablen ausgeführt.
 
'''Beispiele'''
 
<div style="margin-left:0cm;margin-right:0cm;">for X in hans heinz karl luise do echo $X done </div>
 
Das Programm hat folgende Ausgabe:
 
<div style="margin-left:0cm;margin-right:0cm;">hans
heinz
karl
luise</div>
<div style="margin-left:0cm;margin-right:0cm;">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</div>
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># Durchsuche Kapitel zur Erstellung einer Wortliste (wie fgrep -f):</nowiki>
for item in $(cat program_list) # cat: Datei ausgeben
do
    echo "Pruefung der Kapitel auf"
    echo "Referenzen zum Programm $item ..."
    grep -c "$item.[co]" chap* # grep: nach Muster suchen
done</div>
 
=== for-Schleife mit Parametern ===
 
<div style="margin-left:0cm;margin-right:0cm;">for selector
  do
  Kommandofolge
done</div>
 
Die Selektor-Variable wird nacheinander durch die Parameter $1 bis $n 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.
 
<div style="margin-left:0cm;margin-right:0cm;">for FF
  do
  cp $FF ${FF}.bak
done</div>
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh </nowiki>   
<nowiki># Seitenweises Formatieren der Dateien, die auf der </nowiki>
<nowiki># Befehlszeile angegeben wurden, und speichern des </nowiki>
<nowiki># jeweiligen Ergebnisses:</nowiki>
for file do
    pr $file > $file.tmp # pr: Formatiert Textdateien
done</div>
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># Ermittle einen Ein-Wort-Titel aus jeder Datei und </nowiki>
<nowiki># verwende ihn als neuen Dateinamen:</nowiki>
for file do
    name=`sed -n 's/NAME: //p' $file`
    <nowiki># sed: Skriptsprache zur Textformatierung</nowiki>
    mv $file $name
    <nowiki># mv: Datei verschieben bzw. umbenennen</nowiki>
done</div>
 
== 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:
 
<div style="margin-left:0cm;margin-right:0cm;">while Bedingung
do
Befehle
done</div>
 
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'''
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Zeilenweise Ausgabe aller Aufrufparameter:</nowiki>
while [ -n "$1"]; do
  echo $1
  shift  <nowiki># mit shift werden die Parameter nach </nowiki>
  <nowiki># Links geshiftet (aus $2 wird $1) </nowiki>
done  </div>
 
'''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:
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Ausgabe der Zahlen von 1 bis 100:</nowiki>
i=1
while [ $i -le 100 ]
do
    echo $i
    i=`expr $i + 1`
done</div>
 
'''Weitere Beispiele'''
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
while who | grep "^root "
do sleep 30
done
echo Die Katze ist aus dem Haus, Zeit, dass die Mäuse tanzen!</div>
 
'''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.
 
<div style="margin-left:0cm;margin-right:0cm;">while Bedingung
  do
  Kommandofolge
  done</div>
 
Solange der Bedingungsausdruck den Wert 'true' liefert, wird die Schleife ausgeführt.
 
'''Warten auf eine Datei (z. B. vom Hintergrundprozess) '''
 
<div style="margin-left:0cm;margin-right:0cm;">while [ ! -f foo ]
  do
  sleep 10 # Wichtig damit die Prozesslast nicht zu hoch wird
done</div>
 
'''Pausenfüller für das Terminal Abbruch mit DEL-Taste '''
 
<div style="margin-left:0cm;margin-right:0cm;">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</div>
 
'''Umbenennen von Dateien durch Anhängen eines Suffix '''
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># Aufruf change suffix datei(en)</nowiki>
if [ $# -lt 2 ] ; then
  echo "Usage: `basename $0` suffix file(s)"
else
  SUFF=$1 # Suffix speichern
  shift
  while [ $# -ne 0 ] # solange Parameter da sind
  do
  mv $1 ${1}.$SUFF # umbenennen
  shift
  done
fi</div>
 
'''Umbenennen von Dateien durch Anhängen eines Suffix Variante 2 mit for '''
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># Aufruf change suffix datei(en)</nowiki>
if [ $# -lt 2 ] ; then
  echo "Usage: `basename $0` suffix file(s)"
else
  SUFF=$1 # Suffix speichern
  shift
  for FILE
  do
  mv $FILE ${FILE}.$SUFF # umbenennen
  shift
  done
fi</div>
 
== until-Anweisung ==
 
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.
 
<div style="margin-left:0cm;margin-right:0cm;">until Bedingung
  do
  Kommandofolge
done</div>
 
Die Schleife wird solange abgearbeitet, bis Bedingungsausdruck einen Wert ungleich Null liefert.
 
<u>Beispiel</u>
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># warten auf Datei foo</nowiki>
until [ -f foo ]
  do
  sleep 10
done</div>
 
<u>Warten auf einen Benutzer</u>
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># warten, bis sich der Benutzer hans eingeloggt hat</nowiki>
TT=`who | grep -c "hans"`
until [ $TT -gt 0 ]
  do
  sleep 10
  TT=`who | grep -c "hans"`
done</div>
<div style="margin-left:0cm;margin-right:0cm;"><nowiki># warten, bis sich der Benutzer hans eingeloggt hat</nowiki>
<nowiki># Variante 2 – kuerzer</nowiki>
until [ `who | grep -c "hans"` -gt 0 ]
  do
  sleep 10
done</div>
 
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.
 
<u>Beispiel</u>
 
Hier wird die Bedingung nicht per test, sondern mit dem Rückgabewert des Programms grep formuliert.
 
<div style="margin-left:0cm;margin-right:0cm;"><nowiki>#!/bin/sh</nowiki>
<nowiki># Warten, bis sich der Administrator einloggt:</nowiki>
until who | grep "root"; do
<nowiki># who: Liste der Benutzer</nowiki>
<nowiki># grep: Suchen nach Muster</nowiki>
    sleep 30 # sleep: warten
done
echo "Der Meister ist anwesend"</div>

Aktuelle Version vom 14. Oktober 2025, 10:30 Uhr

Seiten in der Kategorie „Bash/Kontrollstrukturen“

Folgende 4 Seiten sind in dieser Kategorie, von 4 insgesamt.