Der read
Befehl liest aus seinem Standardeingabestream und weist der Variablen zu, was gelesen wird file
(es ist etwas komplizierter, siehe lange Diskussion hier ). Der Standardeingabestream stammt aus dem Here-Dokument, das nachher in die Schleife umgeleitet wird done
. Wenn keine Daten von irgendwoher angegeben werden , werden diese interaktiv vom Terminal gelesen. In diesem Fall hat die Shell jedoch angeordnet, ihren Eingabestream mit dem Here-Dokument zu verbinden.
while read
bewirkt, dass die Schleife iteriert, bis der read
Befehl einen Exit-Status ungleich Null zurückgibt. Dies geschieht, wenn Fehler auftreten oder (am häufigsten) wenn keine Daten mehr gelesen werden müssen (der Eingabestream befindet sich am Ende der Datei).
Die Konvention ist, dass jedes Dienstprogramm, das der aufrufenden Shell einen Fehler oder "falsch" oder "nein" signalisieren möchte, dies tut, indem es einen Exit-Status ungleich Null zurückgibt. Ein Null-Exit-Status signalisiert "true" oder "yes" oder "no error". Dieser Status, den Sie überprüfen möchten, ist in verfügbar $?
(nur vom zuletzt ausgeführten Dienstprogramm). Der Exit-Status kann in if
Anweisungen und while
Schleifen oder überall dort verwendet werden, wo ein Test erforderlich ist. Zum Beispiel
if grep -q 'pattern' file; then ...; fi
Ein Here-Dokument ist eine Form der Umleitung . In diesem Fall handelt es sich um eine Umleitung in die Schleife. Alles in der Schleife könnte daraus lesen, aber in diesem Fall ist es nur der read
Befehl, der dies tut. Lesen Sie hier die Dokumente. Wenn die Eingabe aus einer normalen Datei stammte, wäre die letzte Zeile gewesen
done <filename
Wenn Sie die Schleife als einen einzigen Befehl betrachten, ist dies möglicherweise intuitiver:
while ...; do ...; done <filename
Das ist ein Fall von
somecommand <filename
Einige Shells unterstützen auch "Here-Strings" mit <<<"string"
:
cat <<<"This is the here-string"
DavidFoerster weist darauf hin, dass, wenn eines der beiden Skripte x.sh
und y.sh
Lesevorgänge von der Standardeingabe, ohne explizit Daten zum Lesen aus einer Datei oder von einem anderen Ort zu erhalten, die gelesenen Daten tatsächlich aus dem hier gezeigten Dokument stammen.
Bei einem x.sh
, der nur enthält read a
, würde die Variable a
die Zeichenfolge enthalten y.sh
, und das y.sh
Skript würde niemals ausgeführt. Dies liegt an der Tatsache, dass die Standardeingabe für alle Befehle in der while
Schleife umgeleitet wird (und auch von jedem aufgerufenen Skript oder Befehl "geerbt" wird) und die zweite Zeile "verbraucht" wird, x.sh
bevor die while
Schleife read
sie lesen kann.
Wenn dieses Verhalten unerwünscht ist, kann es vermieden werden, ist aber etwas schwierig .
Es schlägt fehl, weil es ;
vorher keine oder eine neue Zeile gibt done
. Ohne ;
oder ohne Zeilenumbruch done
wird das Wort done
als Argument von genommen source
und die Schleife wird außerdem nicht richtig geschlossen (dies ist ein Syntaxfehler).
Es ist fast wahr, dass jede ;
durch eine neue Zeile ersetzt werden kann (zumindest wenn es sich um ein Befehlsbegrenzer handelt). Es signalisiert das Ende eines Befehls, wie auch |
, &
, &&
und ||
(und wahrscheinlich auch andere , die ich vergessen habe).
read
Befehl, der dies tut." - Einige oder alle Shell-Skripte (und ihre rekursiv aufgerufenen Befehle) können aus der Standardeingabe lesen und die Schleifenaufrufe ändern.... done 3<<-EOF
) und lassen Sie denread
Befehl aus Einheit 3 (while read file <&3; do ...
) lesen .Sie erstellen tatsächlich ein Objekt als Dokument und leiten es dann zurück in eine while-Schleife, die es Zeile für Zeile liest, bis keine Zeilen mehr vorhanden sind, und führen einen Quellbefehl in dieser Zeile aus.
Eine andere Möglichkeit, es auszuführen, ist wie folgt:
Angenommen, die Linien
waren in einer Datei namens:
Wir könnten ausführen
Das hier gezeigte Dokument macht die Dinge interaktiver, aber das obige Beispiel kann es Ihnen ermöglichen, es besser zu verstehen.
quelle