È possibile utilizzare più qui-documenti in bash?


14

È possibile utilizzare più documenti qui per fornire input a un comando in bash?

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

Ovviamente, in entrambi i casi, il secondo here-doc viene usato come stdin e sostituisce il primo riferimento. La soluzione è usare echos invece?

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

Inoltre, per qualche motivo, usare una combinazione non ha funzionato per me. Perché dovrebbe essere?

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

C'è qualche motivo dietro il fatto che si desidera utilizzare due documenti qui anziché combinarli in uno?
fagioli

1
@beans In realtà mi sono imbattuto in esso durante il test pastecon input fittizi. Suppongo di poter pensare ad alcuni altri scenari. Se avessi avuto uno script con testo pre-manipolato in alcune variabili, allora potrei voler fare qualcosa per entrambi con un comando che prende solo i file, ad esempio diff.
Sparhawk,

Un altro caso d'uso (Ho trovato questo usando qui-docs per creare uno script di shell): si vuole qualche riga con l'espansione delle variabili e poi alcuni righe senza: cat <<EOF1 <<"EOF2".
Toby Speight,

Risposte:


18

Tu puoi fare:

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

Può esserci solo uno stdin, in quanto esiste solo un descrittore di file 0.

cat << EOF
eof
EOF

è l'abbreviazione di:

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

E:

cat <<< foo

è:

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

Devi decidere cosa aprire sul descrittore di file 0.

cat <(echo foo)

È:

cat /dev/fd/123

Dove si 123trova un descrittore di file in una pipe e, in parallelo, bash viene eseguito echo fooin un altro processo con lo stdout reindirizzato all'altra estremità della pipe.

Dopo aver passato un nome file a cat, catnon leggere più da stdin. Avresti bisogno di:

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

O:

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

( -è dire catdi leggere dallo stdin).


1
cat <<EOFnon è esattamente lo stesso di cat /dev/fd/0...: in quest'ultimo caso catvede il nome del file e fa l'apertura.
Mikel,

@Mikel, intendevo dire che è funzionalmente equivalente . Quando non viene passato alcun argomento, si catlegge dal suo fd0, come se fosse passato un argomento di -o /dev/fd/0(anche se su Linux (e solo Linux), l'apertura /dev/fd/0non è esattamente come duplicare il descrittore di file 0).
Stéphane Chazelas,

Sono stato molto sorpreso dal /dev/fd/3 3<< E1costrutto e ora mi chiedo cosa siano esattamente gli oggetti in / dev / fd /. Ho pensato che in qualche modo appaiano magici dopo che il processo ha aperto un file da qualche parte sul filesystem con l'eccezione di 1 e 2 che sono lì di default per ogni processo. Ma nel tuo esempio stai usando i descrittori di file 3 e 4 che non sono collegati ad alcun file reale tranne che per quel reindirizzamento di input. Non riesco a comprenderlo nel mio modello mentale di descrittori di file. E se il processo volesse aprire un altro file, saprebbe che deve usare fd 5? I fd devono essere 3, 4, 5 .. o può essere qualsiasi cosa?
calavera.info

@ calavera.info, sembra che tu voglia creare una domanda di follow-up.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.