Apa perbedaan antara keempat perintah (fifo, substitusi proses, pengalihan ...)

8

Tujuan saya adalah membuat server gema sederhana menggunakan ncdan tunggal fifo. Saya tidak mencari cara terbaik untuk melakukannya, saya hanya mencoba memahami semantik dari perintah berikut (ketika garpu terjadi, mengapa, apa yang berubah, mengapa perintah berperilaku berbeda ...).

Saya menggunakan Bash, jadi saya tidak yakin jika semua perintah akan bekerja dengan POSIX shatau zsh, ksh...

Berikut adalah empat perintah yang saya sebutkan dalam judul (dengan asumsi saya sudah melakukannya mkfifo fifo):

cat fifo | nc -l localhost 8888 > fifo
exec 3<> fifo && nc -l localhost 8888 <&3 >&3 && exec 3>&-
nc -l localhost 8888 <(cat fifo) > fifo
nc -l localhost 8888 < fifo > fifo

Sekarang saya mengharapkan 4 perintah untuk melakukan hal yang sama, paling tidak dua perintah terakhir melakukan hal yang sama.

  1. Perintah pertama berperilaku seperti yang diharapkan, server gema sederhana yang dimatikan ketika klien menutup koneksi.
  2. Berperilaku seperti 1.
  3. Saya dapat terhubung ke server, mengirim data, tetapi saya tidak pernah menerima apa pun kembali. Ketika saya menutup koneksi klien, server dimatikan.
  4. Tidak dapat terhubung ke server, server mendengarkan selamanya.
foo
sumber

Jawaban:

8

Kuncinya di sini adalah bahwa membuka FIFO adalah operasi pemblokiran. Satu- opensatunya pengembalian setelah kedua ujungnya terhubung, yaitu setelah fifo terbuka untuk membaca dan menulis.

man fifo (7)

Normally, opening the FIFO blocks until the other end is opened also.

Dalam kasus 1, shell bercabang untuk mengeksekusi pipeline, jadi membuka fifo untuk membaca ( cat fifo) dan membuka fifo untuk menulis ( > fifo) terjadi dalam proses terpisah, sehingga terjadi secara independen.

Dalam kasus ke-2, terbuka untuk membaca dan terbuka untuk menulis ( 3<>fifo) terjadi dalam satu langkah.

Dalam kasus ke-3, <(cat fifo)perluas nama file, mis /dev/fd/42. Jadi seperti Anda sedang berlari nc -l localhost 8888 /dev/fd/42 > fifo. Anda perlu tambahan <untuk menjadi setara, misalnya nc -l localhost 8888 < <(cat fifo) > fifo.

Dalam kasus ke-4, shell mencoba membuka fifo untuk membaca ( < fifo) dan membukanya untuk menulis ( > fifo) sebagai bagian dari proses yang sama. Shell melakukannya satu per satu, dari kiri ke kanan. Jadi ia mencoba membuka fifountuk membaca, dan menghalangi selamanya, menunggu sesuatu terbuka fifountuk ditulis. Saya pikir Anda akan menemukan bahwa dalam kasus ini, ncbahkan tidak pernah memulai, dan port tidak pernah dibuka untuk mendengarkan.

Mikel
sumber
Oh yeah kesalahan konyol di # 3, tetapi pada akhirnya hasilnya tetap sama. Hanya pertanyaan lain yang lebih penasaran daripada yang lain, apakah eksekutif satu-satunya cara untuk membuka fifo untuk r / w dalam satu langkah? Dan adakah cara lain untuk memaksa shell untuk bercabang seperti di # 1? Terima kasih!
foo
1
Shell akan bercabang setiap kali Anda menggunakan jalur pipa, subkulit, atau proses substitusi.
Mikel
2
Koreksi, Anda akan perlu nc ... <>fifo >&0, karena <>fifoterbuka fifountuk membaca dan menulis pada fd 0, dan kami ingin hasilnya juga ada.
Mikel