Ich bin an bash
die eingebaute read
Funktion von while-Schleifen gewöhnt , z.
echo "0 1
1 1
1 2
2 3" |\
while read A B; do
echo $A + $B | bc;
done
Ich habe an einem make
Projekt gearbeitet, und es wurde ratsam, Dateien zu teilen und Zwischenergebnisse zu speichern. Infolgedessen zerlege ich oft einzelne Zeilen in Variablen. Während das folgende Beispiel ziemlich gut funktioniert,
head -n1 somefile | while read A B C D E FOO; do [... use vars here ...]; done
Es ist irgendwie dumm, weil die while-Schleife nie mehr als einmal ausgeführt wird. Aber ohne die while
,
head -n1 somefile | read A B C D E FOO; [... use vars here ...]
Die gelesenen Variablen sind immer leer, wenn ich sie benutze. Ich habe dieses Verhalten nie bemerkt read
, weil ich normalerweise while-Schleifen verwenden würde, um viele ähnliche Zeilen zu verarbeiten. Wie kann ich bash
das read
eingebaute System ohne eine while-Schleife verwenden? Oder gibt es eine andere (oder noch bessere) Möglichkeit, eine einzelne Zeile in mehrere (!) Variablen einzulesen?
Fazit
Die Antworten lehren uns, es ist ein Problem des Scoping. Die Aussage
cmd0; cmd1; cmd2 | cmd3; cmd4
wird so interpretiert, dass die Befehle cmd0
, cmd1
und cmd4
in dem gleichen Umfang ausgeführt werden, während die Befehle cmd2
und cmd3
jeweils ihre eigenen Subshell gegeben und damit verschiedene Bereiche. Die ursprüngliche Shell ist das übergeordnete Element beider Subshells.
… cmd1; | cmd2 …
ist ein Fehler. (2) Wir können das sagencmd2
und bekommencmd3
jeweils ihre eigene Unterschale,cmd1; cmd2 | cmd3; cmd4
indem wir Dinge wieanswer=42 | sleep 0
oder ausprobierencd other/dir | read foo
. Sie werden sehen, dass sich der erste Befehl in jeder Pipeline in einer Subshell befinden muss, da sie den Hauptprozess (übergeordnete Shell) nicht beeinflussen.