Apakah mungkin menggunakan beberapa dokumen di sini di bash?

14

Bisakah seseorang menggunakan beberapa dokumen di sini untuk memberikan input ke perintah dalam bash?

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

Jelas, dalam kedua kasus, dokumen-kedua di sini digunakan sebagai stdin, dan menggantikan referensi pertama. Apakah solusi untuk menggunakan echos?

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

Juga, karena alasan tertentu, menggunakan kombinasi tidak berhasil untuk saya. Kenapa bisa begitu?

$ cat <<<foo <(echo bar)
bar
$ cat <(echo -n foo) <<<bar
foo
Sparhawk
sumber
Apakah ada alasan di balik kenyataan bahwa Anda ingin menggunakan dua dokumen di sini daripada menggabungkannya menjadi satu?
kacang
1
@ kacang, aku benar-benar berlari ke dalamnya ketika menguji pastedengan input dummy. Saya kira saya bisa memikirkan beberapa skenario lain. Jika saya memiliki skrip dengan teks pra-dimanipulasi dalam beberapa variabel, maka saya mungkin ingin melakukan sesuatu untuk keduanya dengan perintah yang hanya mengambil file, misalnya diff.
Sparhawk
Penggunaan-kasus lain (saya menemukan ini menggunakan disini-docs untuk membuat script shell): Anda ingin beberapa baris dengan ekspansi variabel dan kemudian beberapa baris tanpa: cat <<EOF1 <<"EOF2".
Toby Speight

Jawaban:

18

Anda dapat melakukan:

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

Hanya ada satu stdin, karena hanya ada satu file descriptor 0.

cat << EOF
eof
EOF

kependekan dari:

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

Dan:

cat <<< foo

adalah:

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

Anda harus memutuskan apa yang akan dibuka pada deskriptor file 0.

cat <(echo foo)

Adalah:

cat /dev/fd/123

Di mana 123deskriptor file ke pipa, dan secara paralel, bash berjalan echo foodi proses lain dengan stdout dialihkan ke ujung pipa yang lain.

Setelah Anda memberikan nama file cat, cattidak lagi membaca dari stdin. Anda membutuhkan:

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

Atau:

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

( -adalah untuk catmembaca dari stdin).

Stéphane Chazelas
sumber
1
cat <<EOFtidak persis sama dengan cat /dev/fd/0...: dalam kasus terakhir catmelihat nama file dan melakukan buka.
Mikel
@Mikel, apa yang saya maksud adalah bahwa secara fungsional setara . Ketika tidak lulus argumen apa pun, catbaca dari argumennyafd 0 , seolah-olah melewati argumen -atau /dev/fd/0(meskipun di Linux (dan hanya Linux), pembukaan /dev/fd/0tidak persis seperti menduplikasi file descriptor 0).
Stéphane Chazelas
Saya sangat terkejut dengan /dev/fd/3 3<< E1konstruk dan sekarang saya bertanya-tanya apa sebenarnya item di bawah / dev / fd /. Saya pikir mereka entah bagaimana tampak ajaib setelah proses membuka file di suatu tempat di sistem file dengan pengecualian 1 dan 2 yang ada secara default untuk setiap proses. Tetapi dalam contoh Anda, Anda menggunakan deskriptor file 3 dan 4 yang tidak terhubung ke file nyata kecuali untuk pengalihan input. Saya tidak dapat memahaminya dalam model mental saya deskriptor file. Bagaimana jika proses ingin membuka file lain, apakah ia tahu harus menggunakan fd 5? Apakah fds harus menjadi 3, 4, 5 .. atau dapat berupa apa saja?
calavera.info
@ calavera.info, sepertinya Anda ingin membuat pertanyaan tindak lanjut.
Stéphane Chazelas