Anda dapat menggunakan sini-doc dan. sumbernya untuk model kolektor umum yang efisien, ramah-POSIX.
. 8<<-\IOHERE /proc/self/fd/8
command
…
fn() { declaration ; } <<WHATEVER
# though a nested heredoc might be finicky
# about stdin depending on shell
WHATEVER
cat -u ./stdout | ./works.as >> expect.ed
IOHERE
Ketika Anda membuka heredoc, Anda memberi isyarat shell dengan token input IOHERE bahwa ia harus mengarahkan inputnya ke file-deskriptor yang Anda tentukan sampai bertemu ujung lain token pembatas Anda. Saya telah melihat-lihat tetapi saya belum melihat banyak contoh penggunaan nomor pengalihan fd seperti yang saya tunjukkan di atas dalam kombinasi dengan operator heredoc, meskipun penggunaannya jelas ditentukan dalam pedoman dasar perintah shell-perintah POSIX. Kebanyakan orang hanya mengarahkannya ke stdin dan menembak, tetapi saya menemukan sumber scriptlets dengan cara ini dapat menjaga stdin gratis dan aplikasi konstituen mengeluh tentang jalur I / o yang diblokir.
Konten heredoc dialirkan ke deskriptor file yang Anda tentukan, yang kemudian ditafsirkan sebagai shell-code dan dieksekusi oleh. builtin, tetapi bukan tanpa menentukan jalur khusus untuk. . Jika / proc / self path memberi Anda masalah, coba / dev / fd / n atau / proc / $$. Metode yang sama ini bekerja pada pipa, dengan cara:
cat ./*.sh | . /dev/stdin
Mungkin setidaknya tidak bijaksana seperti kelihatannya. Anda dapat melakukan hal yang sama dengan sh, tentu saja, tetapi. Tujuannya adalah untuk mengeksekusi di lingkungan shell saat ini, yang mungkin apa yang Anda inginkan, dan, tergantung pada shell Anda, jauh lebih mungkin untuk bekerja dengan heredoc daripada dengan pipa anonim standar.
Bagaimanapun, seperti yang mungkin Anda perhatikan, saya masih belum menjawab pertanyaan Anda. Tetapi jika Anda berpikir tentang hal itu, dengan cara yang sama heredoc mengalirkan semua kode Anda. Masuk, itu juga memberi Anda satu, sederhana, outpoint:
. 5<<EOIN /dev/fd/5 |\
tee -a ./log.file | cat -u >$(tty)
script
…
more script
EOIN
Jadi semua terminal stdout dari salah satu kode yang dieksekusi di heredoc Anda keluar dari pipa. sebagai hal yang biasa dan dapat dengan mudah diambil dari satu pipa. Saya memasukkan panggilan kucing yang tidak terganggu karena saya tidak jelas tentang arah stdout saat ini, tetapi mungkin redundan (hampir pasti seperti yang tertulis) dan saluran pipa mungkin dapat berakhir tepat di tee.
Anda mungkin juga mempertanyakan kutipan backslash yang hilang dalam contoh kedua. Bagian ini penting untuk dipahami sebelum Anda terjun dan mungkin memberi Anda beberapa ide tentang cara penggunaannya. Sebuah heredoc limiter yang dikutip (sejauh ini kami telah menggunakan IOHERE dan EOIN, dan yang pertama saya kutip dengan backslash, meskipun kutipan 'tunggal' atau "ganda" akan memiliki tujuan yang sama) akan menghalangi shell untuk melakukan ekspansi parameter pada konten, tetapi pembatas tanpa tanda kutip akan membiarkan isinya terbuka untuk ekspansi. Konsekuensi dari ini ketika heredoc Anda. bersumber dramatis:
. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)}
HD
echo $vars
> 4,8,12…
echo $var1 $var51
> 4 104
Karena saya tidak mengutip heredoc limiter, shell memperluas isinya ketika membacanya di dan sebelum menyajikan deskriptor file yang dihasilkan. untuk mengeksekusi. Ini pada dasarnya menghasilkan perintah yang diurai dua kali - yang diperluas. Karena saya backslash mengutip ekspansi parameter $ vars, shell mengabaikan deklarasi pada pass pertama dan hanya menghapus backslash sehingga seluruh isi printf yang diperluas dapat dievaluasi dengan nol saat. bersumber skrip pada pass kedua.
Fungsionalitas ini pada dasarnya adalah persis apa yang dapat disediakan oleh shell eval berbahaya, bahkan jika penawarannya lebih mudah ditangani dalam heredoc daripada dengan eval, dan bisa sama berbahayanya. Kecuali Anda merencanakannya dengan hati-hati, mungkin yang terbaik adalah mengutip pembatas "EOF" sebagai kebiasaan. Hanya mengatakan.
EDIT: Eh, saya melihat kembali ini dan berpikir itu terlalu berlebihan. Jika SEMUA yang perlu Anda lakukan adalah menggabungkan beberapa output menjadi satu pipa maka metode paling sederhana adalah dengan menggunakan:
{ or ( command ) list ; } | tee -a ea.sy >>pea.sy
Curlies akan berusaha menjalankan konten di shell saat ini sedangkan parens akan sub-out secara otomatis. Namun, siapa pun dapat memberi tahu Anda itu dan, setidaknya menurut saya,. solusi heredoc adalah informasi yang jauh lebih berharga, terutama jika Anda ingin memahami cara kerja shell.
Selamat bersenang-senang!