Kita semua tahu mkfifo
dan saluran pipa. Yang pertama membuat pipa bernama , jadi kita harus memilih nama, kemungkinan besar dengan mktemp
dan kemudian ingat untuk membatalkan tautan. Yang lain menciptakan pipa anonim, tidak ada kerumitan dengan nama dan penghapusan, tetapi ujung-ujung pipa terikat dengan perintah dalam pipa, itu tidak benar-benar nyaman entah bagaimana mendapatkan pegangan deskriptor file dan menggunakannya dalam sisanya naskah. Dalam program yang dikompilasi, saya hanya akan melakukannya ret=pipe(filedes)
; di Bash ada exec 5<>file
sehingga orang akan mengharapkan sesuatu seperti "exec 5<> -"
atau "pipe <5 >6"
-Apakah ada sesuatu seperti itu di Bash?
38
Meskipun tidak ada cangkang yang saya tahu dapat membuat pipa tanpa forking, beberapa memang memiliki yang lebih baik daripada pipa dasar cangkang.
Dalam bash, ksh dan zsh, dengan asumsi sistem Anda mendukung
/dev/fd
(saat ini paling banyak dilakukan), Anda dapat mengikat input atau output dari perintah ke nama file:<(command)
memperluas ke nama file yang menunjuk sebuah pipa yang terhubung ke output daricommand
, dan>(command)
memperluas ke nama file yang menunjuk pipa yang terhubung ke inputcommand
. Fitur ini disebut proses substitusi . Tujuan utamanya adalah menyalurkan lebih dari satu perintah ke atau dari yang lain, misalnya,Ini juga berguna untuk memerangi beberapa kekurangan pipa shell dasar. Misalnya,
command2 < <(command1)
setara dengancommand1 | command2
, kecuali statusnya adalahcommand2
. Kasus penggunaan lain adalahexec > >(postprocessing)
, yang setara dengan, tetapi lebih mudah dibaca daripada, menempatkan seluruh sisa skrip di dalamnya{ ... } | postprocessing
.sumber
pipe:[123456]
). Emacs melihat bahwa target symlink bukan nama file yang ada dan cukup membingungkan sehingga tidak membaca file (mungkin ada opsi untuk membacanya, meskipun Emacs tidak suka membuka pipa sebagai file tetap).Bash 4 memiliki coprocesses .
sumber
Pada Oktober 2012 fungsi ini tampaknya masih belum ada di Bash, tetapi coproc dapat digunakan jika semua yang Anda butuhkan tanpa nama / pipa anonim adalah berbicara dengan proses anak. Masalah dengan coproc pada saat ini adalah bahwa ternyata hanya satu yang didukung pada suatu waktu. Saya tidak tahu mengapa coproc mendapatkan batasan ini. Mereka seharusnya merupakan peningkatan dari kode latar belakang tugas yang ada (the & op), tapi itu pertanyaan bagi penulis bash.
sumber
coproc THING { dothing; }
Sekarang FD Anda sudah masuk${THING[*]}
dan Anda dapat menjalankancoproc OTHERTHING { dothing; }
dan mengirim dan menerima barang-barang ke dan dari keduanya.man bash
, di bawah judul BUGS, mereka mengatakan ini: Mungkin hanya ada satu proses aktif pada satu waktu . Dan Anda mendapat peringatan jika Anda memulai coproc kedua. Tampaknya berfungsi, tetapi saya tidak tahu apa yang meledak di latar belakang.Sementara jawaban @ DavidAnderson mencakup semua pangkalan dan menawarkan beberapa perlindungan yang bagus, hal terpenting yang terungkap adalah bahwa mendapatkan tangan Anda pada pipa anonim semudah
<(:)
, selama Anda tetap di Linux.Jadi jawaban tersingkat dan paling sederhana untuk pertanyaan Anda adalah:
Pada macOS itu tidak akan berfungsi, maka Anda harus membuat direktori sementara untuk menampung fifo yang dinamai hingga Anda dialihkan ke sana. Saya tidak tahu tentang BSD lainnya.
sumber
exec
dilewatkan dan fifo anonim yang dibuka hanya untuk membaca, makaexec
jangan biarkan fifo anonim ini dibuka untuk dibaca dan ditulis menggunakan deskriptor file khusus. Anda harus mengharapkan untuk mendapatkan-bash: /dev/fd/5: Permission denied
pesan, yang merupakan masalah macOS. Saya percaya bug ini adalah bahwa Ubuntu tidak menghasilkan pesan yang sama. Saya akan bersedia mengubah pikiran saya jika seseorang dapat menghasilkan dokumentasi yang mengatakanexec 5<> <(:)
diizinkan.open(..., O_RDWR)
pada satu ujung pipa searah yang disediakan oleh substitusi dan mengubahnya menjadi pipa dua arah dalam satu FD. Anda mungkin benar bahwa seseorang seharusnya tidak mengandalkan ini. :-D Keluaran dari menggunakan piper execline untuk membuat pipa, kemudian repurposing dengan bash<>
: libranet.de/display/0b6b25a8-195c-84af-6ac7-ee6696661765exec 5<>
, lalu masukkanfun() { ls -l $1; ls -lH $1; }; fun <(:)
.Fungsi berikut diuji menggunakan
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
. Sistem operasinya adalah Ubuntu 18. Fungsi ini mengambil parameter tunggal yang merupakan deskriptor file yang diinginkan untuk FIFO anonim.Fungsi berikut diuji menggunakan
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
. Sistem operasinya adalah macOS High Sierra. Fungsi ini dimulai dengan membuat FIFO bernama dalam direktori sementara hanya diketahui proses yang membuatnya . Selanjutnya, deskriptor file dialihkan ke FIFO. Akhirnya, FIFO dibatalkan tautannya dari nama file dengan menghapus direktori sementara. Ini membuat FIFO anonim.Fungsi-fungsi di atas dapat digabungkan menjadi satu fungsi yang akan bekerja pada kedua sistem operasi. Di bawah ini adalah contoh dari fungsi tersebut. Di sini, upaya dilakukan untuk membuat FIFO yang benar-benar anonim. Jika tidak berhasil, maka FIFO bernama dibuat dan dikonversi ke FIFO anonim.
Berikut adalah contoh membuat FIFO anonim, kemudian menulis beberapa teks ke FIFO yang sama.
Di bawah ini adalah contoh membaca seluruh konten FIFO anonim.
Ini menghasilkan output berikut.
Perintah di bawah ini menutup FIFO anonim.
Referensi:
Membuat pipa anonim untuk digunakan
di lain waktu File di Direktori yang Dapat Ditulis secara Publik Berbahaya
Keamanan Script Shell
sumber
Menggunakan jawaban yang bagus dan cerah dari htamas, saya memodifikasinya sedikit untuk menggunakannya dalam satu liner, ini dia:
sumber