Bash-Lesebefehl und Standardumleitung

8

Soweit ich die Bash-Dokumentation verstehe, sind beide | und <stdin umleiten. Also cmd | foound foo < <(cmd)sollte mehr oder weniger gleichwertig sein. Für den Befehl bash-internal read scheint dies jedoch nicht der Fall zu sein. ZB wenn ich eintrete

a=""; b=""; read a b < <(echo a b); echo $a $b

es wird ausgedruckt a b, während

a=""; b=""; echo a b | read a b; echo $a $b

druckt nichts aus. Auf der anderen Seite, wenn ich eintrete

a=""; b=""; cat < <(echo a b) >foo1

a=""; b=""; echo a b | cat > foo2

Die Dateien foo1 und foo2 sind genau gleich. Meine Frage lautet also: Was ist der Unterschied zwischen beiden Formularen, wenn der Lesebefehl beteiligt ist (oder allgemein)? Sie sollten genau dieselbe umgeleitete Eingabe sehen. Während das < <(...)Formular funktioniert, finde ich es ziemlich unlesbar und würde es sehr bevorzugen, das Pipe-Formular zu verwenden.

Elmar Zander
quelle
2
Schauen Sie sich die Antwort auf diese Frage an .
Larsks

Antworten:

10

Das Pipelining wird readin einer Subshell ausgeführt, während die Prozessersetzung dies nicht tut. In den meisten Anwendungsfällen ist dies kein Problem, aber in diesem Fall möchten Sie die Shell direkt beeinflussen (indem Sie Variablen bearbeiten). Da readin einer Subshell aufgerufen wurde, ist nur die Subshell betroffen. Daher müssen alle Aktionen, die Sie möglicherweise ausführen möchten, auch in der Subshell ausgeführt werden. zum Beispiel:

echo a b | { read a b ; echo "$a" "$b" ; }
Chris Down
quelle
Ja, vielen Dank. Ich habe vorher nicht über dieses Subshell-Problem nachgedacht, aber das klärt alles auf. Ich habe auch [ tldp.org/LDP/abs/html/gotchas.html#BADREAD (dies) jetzt im Advanced Bash Scripting Guide gefunden. Sie empfehlen stattdessen die Verwendung des Befehls [ tldp.org/LDP/abs/html/internal.html#SETPOS (( set)) , um die Werte den Positionsparametern zuzuweisen.
Elmar Zander
2
@ElmarZander - Verwenden Sie nicht den berüchtigten "Advanced" Bash Scripting-Leitfaden von TLDP, sondern lernen Sie, Fehler und keine Skripte zu schreiben. Es gibt Orte, an denen es schlecht geschrieben ist, und viele weitere Orte, an denen es einfach falsch ist. Ich würde stattdessen BashGuide empfehlen .
Chris Down