Beberapa pipa unix tidak berfungsi

7

Pipa pertama ini berfungsi dengan baik (mencetak "c"):

echo "a" | sed 's/a/b/' | sed 's/b/c/'

Yang ini tidak melakukan apa yang saya harapkan (tidak ada yang dicetak ketika saya memberi "a" ke fifo saya):

mkfifo fifo;
cat fifo | sed 's/a/b/' | sed 's/b/c/' 

Namun, jika saya menghapus perintah "sed" kedua dari pipa yang terakhir, saya mendapatkan cetakan "b". Saya pikir pemahaman saya tentang pipa dan pengalihan harus terlalu sederhana. Dapatkah seseorang menjelaskan kepada saya cara memperbaiki kasus ke-2 sehingga saya dapat menjalankan dua perintah berturut-turut pada isi fifo?

(perhatikan ini bukan masalah khusus untuk fifo, perilaku yang sama terjadi dengan netcat juga. Saya memposting pertanyaan serupa tentang netcat tetapi tidak mendapat jawaban)

Sridhar Sarnobat
sumber
2
Kode Anda berfungsi untuk saya. Mungkin, Anda bisa menguraikan lebih detail tentang bagaimana Anda "memberi makan 'a'" ke fifo Anda.
John1024
Seperti @ John1024 berkata, WorksForMe .
Bob
Aku juga, tidak masalah sama sekali.
MariusMatutiae
echo "a" >fifo
Sridhar Sarnobat
Sepertinya ini terkait penyanggaan. Apa versi sed yang Anda gunakan? GNU sed version 4.2.1
Milik

Jawaban:

8

Gunakan opsi -u( --unbuffered) dari sed, jadi ia menulis outputnya, alih-alih mengumpulkannya terlebih dahulu untuk menulis cepat dan besar nanti.

cat fifo | sed -u 's/a/b/' | sed -u 's/b/c/'

cat selalu tanpa gangguan.

Jika ini bukan tentang sed, tetapi beberapa program dengan buffering output, tetapi tanpa opsi untuk menonaktifkannya, ada alat yang dapat membantu untuk memaksa buffering off - lihat man unbufferdan man stdbuf.

Jika itu adalah skrip shell, itu harus di-unbuffered secara default: ketika sebuah perintah membuat output di skrip, dan keluar, outputnya memerah. Jika tidak, Anda menggunakan unbuffer di dalam skrip shell.

Untuk latar belakang, lihat ikhtisar tentang penyangga stdio ini .

Volker Siegel
sumber
Misalkan alih-alih sed, saya punya skrip kustom sendiri. Apa yang akan saya lakukan dalam kasus ini untuk menghindari buffering? Atau haruskah itu tidak dibangun secara default?
Sridhar Sarnobat
Hanya beberapa tindak lanjut - jika saya ingin menggunakan ekspresi reguler perl dengan buffering, itu akan menjadi sepertinc -k -l 4458 | perl -ne 's{HTTP}{FTP}g; $|++;print $_' | perl -ne 's{FTP}{RTSP}g; $|++;print $_'
Sridhar Sarnobat
Ya apa maksudmu Apakah ada masalah, atau ini contohnya? Oh, dan Anda dapat menggunakan ssed -Rjika Anda suka seddengan ekspresi reguler perl.
Volker Siegel
Maaf, itu bukan pertanyaan. Saya minta maaf karena tidak jelas, itu hanyalah contoh lain dari konsep yang sama. Sayangnya sudah terlambat bagi saya untuk mengedit komentar itu. Saya tidak tahu dan bisa mengerti Perl regex. Mungkin saya harus mulai menggunakannya daripada sekarang.
Sridhar Sarnobat
Oh tidak masalah!
Volker Siegel