GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash-Skripting (II)

Dies ist der zweite Artikel einer Serie, die sich auf Gnu Bash-Skripting konzentriert. Im ersten Bash-Skripting-Artikel haben wir gerade das einfachste Skript erstellt:einfache Befehle, einer nach dem anderen. Wir haben auch die Verwendung einiger Variablen gesehen. Dieser Artikel behandelt Bash-Kontrollstrukturen.

Kontrollstrukturen

Wie ich im vorherigen Artikel gesagt habe, ist Faulheit der Schlüssel zum Erfolg. Wenn ich einige Befehle ausführen muss, eine Weile später dieselben Befehle in derselben Reihenfolge, öffne ich beim dritten Mal einen Texteditor und füge diese Befehle ein, um sie als Skript zu speichern.

Nach ein paar Tagen beginnt dieses Skript zu wachsen, sowohl in der Erweiterung als auch in der Komplexität. Ich brauche Möglichkeiten, um den Ausführungsfluss zu steuern, zum Beispiel:

  • wenn etwas passiert, tun Sie etwas, oder wenn etwas nicht passiert, tun Sie etwas anderes;
  • während etwas passiert, tun Sie etwas immer wieder oder tun Sie etwas immer wieder;
  • oder abhängig vom Wert einer Variablen oder dem, was passiert ist, tue dies oder jenes,
  • usw.

Dafür sind Bash-Kontrollstrukturen gedacht (eigentlich in Bash oder einer anderen Programmiersprache). Aber zuerst müssen wir Folgendes wissen:

Exit-Status

Aus der Bash-Manpage:

«Der Exit-Status eines ausgeführten Befehls ist der Wert, der vom Waitpid-Systemaufruf oder einer entsprechenden Funktion zurückgegeben wird. Ausgangsstatus liegen zwischen 0 und 255. (…) Ein Exit-Status von Null zeigt einen Erfolg an (oder gleich „true“). Ein Exit-Status ungleich Null weist auf einen Fehler hin (oder gleich 'false').(…. Zum Beispiel:) Wenn ein Befehl nicht gefunden wird, gibt der zu seiner Ausführung erstellte untergeordnete Prozess den Status 127 zurück. Wenn ein Befehl gefunden wird, aber nicht ausführbar ist, der Rückgabestatus ist 126 ».

tl;dr:Ausgangsstatus von 0 bedeutet wahr , Erfolg; jeder andere Wert bedeutet falsch . Es ist wichtig, dies zu lernen, da das Treffen von Wahr/Falsch-Entscheidungen bedeutet, den Beendigungsstatus eines Befehls zu überprüfen.

Bash speichert den Exit-Status des zuletzt ausgeführten Befehls in $? Variable.

wenn-dann-sonst

Dies ist die falls etwas passiert (Etwas passiert bedeutet ein Befehl mit einem Exit-Status von Null) mach etwas , oder etwas anderes tun. Die Syntax lautet:

if command
then
	command1
	command2
	...
else
	commandA
	commandB
	...
fi

Wie Sie auf dem Screenshot sehen können, kann es in einer einzigen Zeile geschrieben werden, wobei jeder Befehl durch ein Semikolon getrennt wird:

if command; then command1; command2;...; else commandA; commandB;...;fi

Abhängig von der Komplexität des Wenn-Dann-Blocks kann es einfacher oder schwerer zu lesen sein, den „Einzeiler“-Stil zu lesen.

Was ist, wenn Sie einen Befehl ausführen möchten, wenn etwas passiert, führen Sie einen anderen Befehl nur aus, wenn etwas anderes das passiert? Verwenden Sie das Schlüsselwort elif (else if):

if command
then
	command1
	command2
	...
elif other_command
	commandA
	commandB
	...
else
	another block of commands
fi

Ein If-Then-Else-Block endet mit dem Schlüsselwort fi (falls rückwärts).

String- und Zahlenvergleich

Erinnerst du dich an Variablen? häufig passiert etwas ist, dass wir abhängig vom Wert einer Variablen einige Befehle oder andere ausführen möchten.
Um zu vergleichen, ob ein String einem Wort gleicht oder eine Zahl niedriger als andere ist, verwenden wir den Befehl test . Die allgemeine Syntax lautet:

test expression

Wenn Ausdruck weggelassen wird, gilt es als falsch (Ausgangsstatus> 0). Wenn Ausdruck ist nur eine Textfolge, es ist wahr. Dies könnte z. B. knifflig sein:

$ test false; echo $?
0

Wir testen nicht den Exit-Status des Befehls false (es gibt einen Befehl false ), aber die Zeichenfolge false gegen nichts. Die andere Möglichkeit, den Testbefehl auszuführen, besteht darin, den Ausdruck in eckige Klammern einzuschließen. Dieser andere Weg ist innerhalb eines if-then-else-Blocks einfacher zu lesen.

Operanden wahr, wenn
Ausdruck wahr
! Ausdruck false (negiert Ausdruck)
AusdruckA -ein AusdruckB Und. beide Ausdrücke sind wahr
AusdruckA -o AusdruckB Oder. Einer der Ausdrücke ist wahr
Zeichenfolge1 =Zeichenfolge2 beide Zeichenfolgen sind gleich
Zeichenfolge1 !=Zeichenfolge2 Strings sind unterschiedlich
int1 -eq int2 Ganzzahl1 ist gleich Ganzzahl2
int1-ge int2 int1>=int2
int1 -gt int2 int1> int2
int1 -le int2 int1 <=int2
int1 -lt int2 int1
int1 -ne int2 int1 ist nicht gleich int2
-e-Datei Datei existiert
-d Verzeichnis Datei existiert und ist ein Verzeichnis

Es gibt noch mehr Ausdrücke, das sind die, die ich für wichtiger halte. Lesen Sie die Manpage für Test, um die anderen Ausdrücke zu lernen.

Achten Sie darauf, dass zwischen den beiden eckigen Klammern und dem Ausdruck ein Leerzeichen steht. Jetzt können wir test verwenden, um etwas zu tun basierend auf dem Wert einer Variablen. Zum Beispiel:

Fall

Wenn wir eine Variable mit mehreren Werten testen möchten, können wir unserem if-then-else-Block mehrere elif wie folgt hinzufügen:

if [ $a = "value1" ]
then
	command1 for value1
	...
	commandN for value1
elif [ $a = "value2" ] 
then
	command1 for value2
	...
	commandN for value2
...
elif [ $a = "valueN" ] 
then
	command1 for valueN
	...
	commandN for valueN
else
	command1 for every other value
	...
	commandN for every other value
fi

Oder wir können es durch einen case-Befehl ersetzen, der einfacher zu lesen und zu schreiben ist:

case expression in
	value1)
		command1 for value1
		...
		commandN for value1
		;;
	value2)
		command1 for value2
		...
		commandN for value2
		;;
	...
	*)
		command1 for every other value
		...
		commandN for every other value
		;;
esac

Außerdem weniger Tastenanschläge, vergessen Sie nicht, faul genug zu sein, um den Computer für Sie arbeiten zu lassen. Der letzte Wert * ist der Standardfall, jeder andere Wert, der zuvor nicht abgeglichen wurde. Fall rückwärts, esac , ist analog zur fi-Anweisung. Wenn die ;; -Operator verwendet wird, werden nach der ersten Musterübereinstimmung keine weiteren Übereinstimmungen versucht. Um das nächste Muster zu testen, verwenden Sie ;;* Operator. Zum Beispiel:

während und bis

Während etwas immer und immer wieder getan wird, während etwas passiert. Und until ist dasselbe, aber negiert (etwas immer wieder tun, während etwas nicht passiert). Die allgemeine Syntax lautet:

while command
do
	command1
	command2
	...
	commandN
done

Um etwas zu tun, während etwas nicht passiert (d. h. der Existent-Status ist von 0 verschieden), ersetzen Sie while durch until. Siehe einige Beispiele:

Beachten Sie, dass sie nicht die gleiche Ausgabe erzeugt haben. Wenn $a im While-Block den Wert 4 erreicht, ist er nicht kleiner als 4, sodass der Test als falsch ausgewertet wird (und der Exit-Code> 0 ist). Wenn $a im until-Block den Wert 4 erreicht, ist es nicht größer als 4.

Eine Uhr in Ihrem Terminal

Manchmal teste ich einen Cronjob und das macht mir Angst, bis er ausgeführt wird. Ich verwende den true-Befehl (der, wie Sie sich vielleicht gedacht haben, einen 0-Exit-Status erzeugt) als Bedingung und führe den Befehl date immer wieder aus:

while true
do
	date
	sleep 1
	clear
done

Dies würde foverer laufen, aber ich kann mit ctrl-c unterbrechen.

für-in -tun

Diese Art von Schleife iteriert über eine bereitgestellte Liste, wobei jedes Element einer Variablen zugewiesen wird. Syntax:

for i in list of words
do
	command1
	...
	commandN
done

Dies ist in einem Beispiel einfacher zu sehen:

Bleib dran

Die Dinge werden immer komplexer, aber wir möchten, dass unsere Skripte einige Entscheidungen treffen, um dies oder jenes zu tun. Ich sollte andere Themen behandeln, aber dieser Artikel über Bash-Kontrollstrukturen ist zu lang geworden.

Bei den nächsten werde ich Pipes und Redirection behandeln. Ich werde wahrscheinlich mit den Beispielen auf diese Bash-Kontrollstrukturen zurückkommen, so etwas wie die Verwendung der Ausgabe eines Befehls in einer for-in-Schleife und solche Sachen.


Linux
  1. Bash-Trap-Befehl erklärt

  2. Bash-Scripting(I)

  3. Der „eval“-Befehl in Bash?

  4. Bash-Exportbefehl

  5. Führen Sie den Bash-Befehl auf der Jenkins-Pipeline aus

Bash-Scripting – String-Manipulation

Bash-Scripting – Printf-Befehl mit Beispielen erklärt

Bash-Skripting – Case-Statement

So verwenden Sie den Datumsbefehl in Bash-Skripten unter Linux

Bash-Scripting(III)

Bash Beginner Series #2:Variables in Bash Shell Scripting verstehen