Ist es möglich, mehrere Here-Docs in Bash zu verwenden?

14

Kann man mehrere here-docs verwenden, um einen Befehl in bash einzugeben?

$ cat <<<foo <<<bar
bar
$ cat <<EOF1 <<EOF2
> foo
> EOF1
> bar
> EOF2
bar

Offensichtlich wird in beiden Fällen der zweite Here-Doc als Standard verwendet und ersetzt den ersten Verweis. Ist die Lösung, echostattdessen s zu verwenden?

$ cat <(echo -n foo) <(echo bar)
foobar

Aus irgendeinem Grund hat die Verwendung einer Kombination auch bei mir nicht funktioniert. Warum sollte das so sein?

$ cat <<<foo <(echo bar)
bar
$ cat <(echo -n foo) <<<bar
foo
Sparhawk
quelle
Gibt es einen Grund für die Tatsache, dass Sie zwei Here-Dokumente verwenden möchten, anstatt sie zu einem zu kombinieren?
Bohnen
1
@beans Ich bin tatsächlich darauf gestoßen, als ich pastemit Dummy-Eingängen getestet habe . Ich denke, ich kann mir ein paar andere Szenarien vorstellen. Wenn ich ein Skript mit vorab manipuliertem Text in einigen Variablen gehabt hätte, dann möchte ich vielleicht mit einem Befehl, der nur Dateien akzeptiert, etwas mit beiden machen diff.
Sparhawk
Ein weiterer Anwendungsfall (Ich fand das hier-docs mit einem Shell - Skript erstellen): Sie wollen ein paar Zeilen mit variabler Ausdehnung und dann einige Zeilen ohne: cat <<EOF1 <<"EOF2".
Toby Speight

Antworten:

18

Du kannst tun:

cat /dev/fd/3 3<< E1 /dev/fd/4 4<< E2
foo
E1
bar
E2

Es kann nur eine Standardeingabe geben, da es nur einen Dateideskriptor 0 gibt.

cat << EOF
eof
EOF

Kurzform für:

cat /dev/fd/0 0<< EOF
eof
EOF

Und:

cat <<< foo

ist:

cat /dev/fd/0 0<<< foo

Sie müssen sich überlegen, was in Dateideskriptor 0 geöffnet werden soll.

cat <(echo foo)

Ist:

cat /dev/fd/123

Wo 123ist ein Dateideskriptor zu einer Pipe, und parallel dazu wird Bash echo fooin einem anderen Prozess ausgeführt, wobei die stdout zum anderen Ende der Pipe umgeleitet wird.

Sobald Sie einen Dateinamen an übergeben cat, wird catnicht mehr von stdin gelesen. Sie brauchen:

cat <(echo foo) /dev/fd/0 << EOF
bar
EOF

Oder:

cat <(echo foo) - << EOF
bar
EOF

( -ist zu erzählen catvon stdin zu lesen).

Stéphane Chazelas
quelle
1
cat <<EOFist nicht genau das gleiche wie cat /dev/fd/0...: in letzterem Fall catsieht der Dateiname und macht das Öffnen.
Mikel
@Mikel, was ich damit gemeint habe ist, dass es funktional äquivalent ist . Wenn kein Argument übergeben wird, wird catvon seiner fd0 gelesen , als ob ein Argument von -oder übergeben wurde /dev/fd/0(obwohl das Öffnen unter Linux (und nur unter Linux) /dev/fd/0nicht genau dem Duplizieren des Dateideskriptors 0 gleicht).
Stéphane Chazelas
/dev/fd/3 3<< E1Konstrukt hat mich sehr überrascht und ich frage mich, was genau unter / dev / fd / steht. Obwohl sie irgendwie magisch erscheinen, nachdem der Prozess eine Datei irgendwo im Dateisystem geöffnet hat, mit Ausnahme von 1 und 2, die standardmäßig für jeden Prozess vorhanden sind. In Ihrem Beispiel verwenden Sie jedoch die Dateideskriptoren 3 und 4, die mit Ausnahme dieser Eingabeumleitung mit keiner echten Datei verbunden sind. Das kann ich in meinem mentalen Modell der Dateideskriptoren nicht nachvollziehen. Was ist, wenn Prozess eine andere Datei öffnen möchte, würde er wissen, dass er fd 5 verwenden muss? Müssen FDS 3, 4, 5 sein ... oder kann es irgendetwas sein?
calavera.info
@ calavera.info, es hört sich so an, als ob Sie eine Folgefrage erstellen möchten.
Stéphane Chazelas