Apa perbedaan antara <<
, <<<
dan < <
dalam bash?
command-line
bash
redirect
Searene
sumber
sumber
Jawaban:
Dokumen di sini
<<
dikenal sebagaihere-document
struktur. Anda membiarkan program tahu apa yang akan menjadi teks akhir, dan setiap kali pembatas itu terlihat, program akan membaca semua hal yang Anda berikan kepada program sebagai input dan melakukan tugas di atasnya.Inilah yang saya maksud:
Dalam contoh ini kita memberi tahu
wc
program untuk menungguEOF
string, lalu ketikkan lima kata, dan kemudian ketikkanEOF
untuk memberi sinyal bahwa kita telah selesai memberikan input. Efeknya, ini mirip dengan berjalanwc
sendiri, mengetik kata-kata, lalu menekanCtrlDDalam bash ini diimplementasikan melalui file temp, biasanya dalam bentuk
/tmp/sh-thd.<random string>
, sedangkan di dash mereka diimplementasikan sebagai pipa anonim. Ini dapat diamati melalui pelacakan panggilan sistem denganstrace
perintah. Gantibash
dengansh
untuk melihat bagaimana/bin/sh
melakukan pengalihan ini.Di sini string
<<<
dikenal sebagaihere-string
. Alih-alih mengetik teks, Anda memberikan string teks yang sudah dibuat sebelumnya ke program. Sebagai contoh, dengan program seperti yangbc
dapat kita lakukanbc <<< 5*4
untuk mendapatkan output untuk kasus tertentu, tidak perlu menjalankan bc secara interaktif.String-bash di sini diimplementasikan melalui file-file sementara, biasanya dalam format
/tmp/sh-thd.<random string>
, yang kemudian tidak terhubung, sehingga membuat mereka menempati beberapa ruang memori sementara tetapi tidak muncul dalam daftar/tmp
entri direktori, dan secara efektif ada sebagai file anonim, yang mungkin masih ada direferensikan melalui file deskriptor oleh shell itu sendiri, dan deskriptor file yang diwarisi oleh perintah dan kemudian diduplikasi ke file deskriptor 0 (stdin) melaluidup2()
fungsi. Ini dapat diamati melaluiDan melalui penelusuran syscalls (output disingkat agar mudah dibaca; perhatikan bagaimana file temp dibuka sebagai fd 3, data ditulis untuk itu, kemudian dibuka kembali dengan
O_RDONLY
flag sebagai fd 4 dan kemudian dihapus tautannya, kemudiandup2()
ke fd 0, yang diwarisicat
kemudian ):Opini: berpotensi karena di sini string menggunakan file teks sementara, itu adalah kemungkinan alasan di sini-string selalu menyisipkan baris baru, karena file teks dengan definisi POSIX harus memiliki garis yang diakhiri dengan karakter baris baru.
Substitusi proses
Seperti yang dijelaskan tldp.org ,
Jadi pada dasarnya ini mirip dengan pemipaan stdout dari satu perintah ke yang lain, misalnya
echo foobar barfoo | wc
. Tetapi perhatikan: di halaman bash Anda akan melihat bahwa itu dilambangkan sebagai<(list)
. Jadi pada dasarnya Anda dapat mengarahkan output dari beberapa perintah (!).Catatan: secara teknis ketika Anda mengatakan
< <
Anda tidak mengacu pada satu hal, tetapi dua pengalihan dengan satu<
dan proses pengalihan dari<( . . .)
.Sekarang apa yang terjadi jika kita hanya memproses substitusi?
Seperti yang Anda lihat, shell membuat deskriptor file sementara di
/dev/fd/63
mana output berjalan (yang menurut jawaban Gilles , adalah pipa anonim). Itu berarti<
mengarahkan kembali deskriptor file itu sebagai input ke perintah.Jadi contoh yang sangat sederhana adalah membuat proses substitusi output dari dua perintah echo ke wc:
Jadi di sini kita membuat shell membuat deskriptor file untuk semua output yang terjadi dalam tanda kurung dan mengarahkan ulang itu sebagai input ke
wc
. Seperti yang diharapkan, wc menerima aliran itu dari dua perintah gema, yang dengan sendirinya akan menghasilkan dua baris, masing-masing memiliki kata, dan tepat kami memiliki 2 kata, 2 baris, dan 6 karakter ditambah dua baris baru dihitung.Catatan Sisi: Substitusi proses dapat disebut sebagai bashism (perintah atau struktur yang dapat digunakan dalam shell canggih seperti
bash
, tetapi tidak ditentukan oleh POSIX), tetapi itu diterapkanksh
sebelum bash sebagai halaman man ksh dan jawaban ini menyarankan. Kerang sukatcsh
danmksh
bagaimanapun tidak memiliki proses substitusi. Jadi bagaimana kita bisa berkeliling mengarahkan output dari beberapa perintah ke perintah lain tanpa proses substitusi? Pengelompokan plus perpipaan!Secara efektif ini sama dengan contoh di atas, Namun, ini berbeda di bawah tenda dari proses substitusi, karena kami membuat stdout dari seluruh subkulit dan stdin
wc
terkait dengan pipa . Di sisi lain, proses substitusi membuat perintah membaca deskriptor file sementara.Jadi jika kita dapat melakukan pengelompokan dengan perpipaan, mengapa kita perlu proses substitusi? Karena terkadang kita tidak bisa menggunakan perpipaan. Pertimbangkan contoh di bawah ini - membandingkan output dari dua perintah dengan
diff
(yang membutuhkan dua file, dan dalam hal ini kami memberikannya dua file deskriptor)sumber
< <
digunakan ketika seseorang mendapatkan stdin dari proses substitusi . Perintah tersebut akan terlihat seperti:cmd1 < <(cmd2)
. Misalnya,wc < <(date)
< <
bukanlah sesuatu dengan sendirinya, dalam hal proses substitusi itu hanya<
diikuti oleh sesuatu yang lain yang mulai dengan<
<<<
pertama kali diterapkan oleh port Unix dari shell rc Plan 9 kemudian diadopsi oleh zsh, bash dan ksh93. Saya tidak akan menyebutnya bashism.echo 'foo' | read; echo ${REPLY}
akan kembali , karena dimulai dalam sub-shell - perpipaan memulai sub-shell. Namun, kembali dengan benar , karena tidak ada sub-shell.foo
read
read < <(echo 'foo'); echo ${REPLY}
foo
< <
adalah kesalahan sintaksis:< <()
adalah subtitusi proses (<()
) yang dikombinasikan dengan pengalihan (<
):Contoh yang dibuat-buat:
Dengan substitusi proses, path ke deskriptor file digunakan seperti nama file. Jika Anda tidak ingin (atau tidak bisa) menggunakan nama file secara langsung, Anda menggabungkan subtitusi proses dengan pengalihan.
Untuk menjadi jelas, tidak ada
< <
operator.sumber
<()
memberikan hal seperti nama file, jadi lebih bermanfaat secara umum -< <()
mengganti stdin di tempat yang mungkin tidak diperlukan. Dalamwc
, yang terakhir kebetulan lebih bermanfaat. Mungkin kurang bermanfaat di tempat lain< <
adalah kesalahan sintaks, Anda mungkin berarticommand1 < <( command2 )
yang merupakan pengalihan input sederhana diikuti oleh substitusi proses dan sangat mirip tetapi tidak setara dengan:Perbedaan dengan asumsi Anda menjalankan
bash
yangcommand1
dijalankan di subkulit dalam kasus kedua ketika sedang berjalan di shell saat ini di yang pertama. Itu berarti variabel yang ditetapkancommand1
tidak akan hilang dengan varian subtitusi proses.sumber
< <
akan memberikan kesalahan sintaksis. Penggunaan yang benar adalah sebagai berikut:Menjelaskan dengan bantuan contoh:
Contoh untuk
< <()
:Pada contoh di atas, input ke loop sementara akan datang dari
ls
perintah yang dapat dibaca baris demi baris danecho
diedit dalam loop.<()
digunakan untuk proses substitusi. Informasi lebih lanjut dan contoh untuk<()
dapat ditemukan di tautan ini:Proses penggantian dan pipa
sumber