Kaufen Sie dieses Shell Scripting Tutorial als PDF für nur $5
Test wird von praktisch jedem geschriebenen Shell-Skript verwendet. Es mag nicht so aussehen, denntest
wird nicht oft direkt aufgerufen. test
wird auf Ihrem System häufiger als
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
aufgerufen, aber hier sind einige Verwendungen und typische Beispiele.
Test wird am häufigsten indirekt über die Anweisungen if
und while
aufgerufen. Das ist auch der Grund, warum Sie in Schwierigkeiten geraten, wenn Sie ein Programm mit dem Namen test
erstellen und versuchen, es auszuführen, da dieses Shell-Builtin anstelle Ihres Programms aufgerufen wird!
Die Syntax für if...then...else...
ist:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
Sie können auch elif
verwenden, etwa so:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Versuchen Sie den folgenden Codeausschnitt, setzen Sie vor dem Ausführen die Variable X auf verschiedene Werte (probieren Sie -1, 0, 1, hallo, tschüss, usw.). Sie können dies wie folgt tun (Dank an Dave für den Hinweis auf die Notwendigkeit, die Variable zu exportieren, wie inVariablen - Teil I. erwähnt):
$ X=5$ export X$ ./test.sh ... output of test.sh ...$ X=hello$ ./test.sh ... output of test.sh ...$ X=test.sh$ ./test.sh ... output of test.sh ...
Dann versuchen Sie es erneut, mit $X
als Name einer bestehenden Datei, wie /etc/hosts
.
test.sh
Beachten Sie, dass wir das Semikolon (;
) verwenden können, um zwei Zeilen miteinander zu verbinden. Dies wird oft getan, um in einfachen if
-Anweisungen ein wenig Platz zu sparen.
Der Backslash (\
) dient einem ähnlichen, aber entgegengesetzten Zweck: Er teilt der Shell mit, dass dies nicht das Ende der Zeile ist, sondern dass die folgende Zeile als Teil der aktuellen Zeile behandelt werden soll. Dies ist nützlich für die Lesbarkeit. Es ist üblich, die folgende Zeile nach einem Backslash (\
) oder Semikolon (;
) einzurücken.
Zum Beispiel wird das Semikolon (;
) oft so verwendet, um die Schlüsselwörter if
und then
zu verbinden:
if ; then echo "X is a file which is newer than /etc/passwd"fi
während der Backslash (\
) verwendet wird, um den einzeiligen Befehl aus Gründen der Lesbarkeit auf zwei Zeilen in der Shell-Skriptdatei aufzuteilen:
&& \ echo "X is a file which is newer than /etc/passwd"
Wie aus diesen Beispielen hervorgeht, kann test
viele Tests für Zahlen, Zeichenketten und Dateinamen durchführen.
Es gibt eine einfachere Möglichkeit, if
-Anweisungen zu schreiben: Die Befehle &&
und ||
geben Code aus, der ausgeführt wird, wenn das Ergebnis wahr bzw. falsch ist.
Diese Syntax ist möglich, weil es eine Datei (oder ein Shell-Builtin) namens gibt, die für while-Schleifen und triviale Sanitychecks empfohlen wird, mit denen man den Leser nicht zu sehr ablenken will.
Beachten Sie, dass, wenn Sie X auf einen nicht-numerischen Wert setzen, die ersten Vergleiche zu der Meldung führen:
Das liegt daran, dass die Vergleiche -lt, -gt, -le und -ge nur für ganze Zahlen ausgelegt sind und bei Strings nicht funktionieren. Die String-Vergleiche, wie z.B. !=
, behandeln "5" gerne als String, aber es gibt keine sinnvolle Möglichkeit, "Hello" als Ganzzahl zu behandeln, so dass die Integer-Vergleiche sich beschweren.
Wenn Sie möchten, dass sich Ihr Shell-Skript vernünftiger verhält, müssen Sie den Inhalt der Variablen überprüfen, bevor Sie sie testen - vielleicht so etwas wie dies:
Auf diese Weise können Sie echo
dem Benutzer eine aussagekräftigere Nachricht geben und das Skript anständig beenden. Die $?
-Variable wird in Variablen - Teil II erklärt, und grep
ist ein kompliziertes Biest, also geht's los: grep
findet Textzeilen, die Ziffern (0-9) und möglicherweise andere Zeichen enthalten, also findet das Caret (^
) in grep
nur die Zeilen, die nicht nur aus Zahlen bestehen. Wir können dann den umgekehrten Weg gehen (indem wir auf Misserfolg und nicht auf Erfolg reagieren). Geht das? >/dev/null 2>&1
leitet alle Ausgaben oder Fehler an das spezielle "Null"-Gerät weiter, anstatt auf den Bildschirm des Benutzers zu gehen.
Vielen Dank an Paul Schermerhorn für die Korrektur - auf dieser Seite wurde behauptet, dass grep -v
funktionieren würde, aber das ist eindeutig viel zu einfach.
Wir können test in while-Schleifen wie folgt verwenden:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Dieser Code fragt so lange nach Eingaben, bis man RETURN drückt (X ist null lang).Danke an Justin Heath für den Hinweis, dass das Skript nicht funktioniert - ich hatte die Anführungszeichen um $X in while
übersehen. Ohne diese Anführungszeichen gibt es nichts zu testen, wenn $X leer ist.
Alexander Weber hat darauf hingewiesen, dass die Ausführung dieses Skripts unordentlich endet:
Das kann mit einem weiteren Test innerhalb der Schleife in Ordnung gebracht werden:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
Beachte auch, dass ich auf dieser Seite zwei verschiedene Syntaxen für if
-Anweisungen verwendet habe. Diese sind:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
Sie müssen einen Bruch zwischen der if
-Anweisung und dem then
-Konstrukt haben. Das kann ein Semikolon oder ein Zeilenumbruch sein, egal welcher, aber es muss einer von beiden zwischen if
und then
stehen.
if echo "You said: $X"
Es wäre schön, einfach zu sagen:
if echo "You said: $X"
aber then
und fi
sind unbedingt erforderlich.
Zurück: Schleifen Weiter: Fall