Melihat "Pipa rusak" dalam situasi ini jarang terjadi, tetapi normal.
Saat Anda menjalankan type rvm | head -1
, bash dieksekusi type rvm
dalam satu proses, head -1
dalam proses lainnya. 1 Stdout of type
terhubung ke ujung "tulis" pipa , stdin dari head
ke ujung "baca". Kedua proses berjalan pada saat bersamaan.
The head -1
proses membaca data dari stdin (biasanya dalam potongan 8 kB), print satu baris (menurut -1
pilihan), dan keluar, menyebabkan "membaca" ujung pipa harus ditutup. Karena rvm
fungsinya cukup panjang (sekitar 11 kB setelah diuraikan dan direkonstruksi oleh bash), ini berarti head
keluar sementara type
masih memiliki beberapa kB data untuk ditulis.
Pada titik ini, karena type
sedang mencoba untuk menulis ke pipa yang ujungnya telah ditutup - pipa yang rusak - fungsi write () yang akan mengembalikan kesalahan EPIPE, diterjemahkan sebagai "Pipa rusak". Selain kesalahan ini, kernel juga mengirimkan sinyal SIGPIPE ke type
, yang secara default membunuh proses segera.
(Sinyal ini sangat berguna dalam shell interaktif, karena sebagian besar pengguna tidak ingin proses pertama tetap berjalan dan mencoba menulis ke mana-mana. Sementara itu, layanan non-interaktif mengabaikan SIGPIPE - itu tidak akan baik untuk daemon yang sudah berjalan lama untuk mati karena kesalahan sederhana - sehingga mereka menemukan kode kesalahan sangat berguna.)
Namun, pengiriman sinyal tidak 100% langsung, dan mungkin ada kasus di mana write () mengembalikan EPIPE dan proses terus berjalan untuk sementara waktu sebelum menerima sinyal. Dalam hal ini, type
dapatkan waktu yang cukup untuk memperhatikan penulisan yang gagal, menerjemahkan kode kesalahan dan bahkan mencetak pesan kesalahan ke stderr sebelum dibunuh oleh SIGPIPE. (Pesan kesalahan mengatakan "-bash: type:" karena type
merupakan perintah built-in dari bash itu sendiri.)
Ini tampaknya lebih umum pada sistem multi-CPU, karena type
proses dan kode pengiriman sinyal kernel dapat berjalan pada core yang berbeda, secara harfiah pada saat yang sama.
Mungkin untuk menghapus pesan ini dengan menambal type
builtin (dalam kode sumber bash) untuk segera keluar ketika menerima EPIPE dari fungsi write ().
Namun, tidak ada yang perlu dikhawatirkan, dan itu tidak terkait dengan rvm
instalasi Anda dengan cara apa pun.
ls
melalui pipahead -1
selama bertahun-tahun, dan hari ini saya menerima pesan pipa yang rusak.Anda dapat memperbaiki pipa yang rusak dengan mengorbankan proses lain dengan memasukkan
tail -n +1
pipa Anda, seperti ini:Ia
+1
memberitahutail
untuk mencetak baris input pertama dan segala sesuatu yang mengikuti. Output akan persis sama seperti jikatail -n +1
tidak ada di sana, tetapi program ini cukup pintar untuk memeriksa output standar dan menutup pipa dengan bersih. Tidak ada lagi pipa yang rusak .sumber
find /var/lib/mysql -xdev -type f -daystart -mmin +5 -print0 | xargs -0 ls -ldt | tail -n +1 | head
diandalkanxargs: ls: terminated by signal 13
. Seperti yang kita tahu, masalahnya adalah salah satu input kelelahan dan hanya ada satu perintah yang berhubungan dengan buffering: dd. Menambahkan| dd obs=1M
ke saluran pipa memperbaiki SIGPIPE untuk kasus penggunaan saya.type rvm | (head -1 ; dd of=/dev/null)
Ini, tentu saja, mirip dengan saran lain karena menyebabkan semua input diproses , tetapidd
harus menjadi program yang paling efisien untuk menangani hal-hal seperti itu.The
write error: Broken pipe
pesan mengacu pada proses penulisan yang mencoba untuk menulis ke pipa tanpa pembaca tersisa di akhir pembacaan yang pipa dan keadaan khusus bahwaSIGPIPE
sinyal diatur untuk diabaikan baik oleh arus atau proses induk. Jika itu adalah proses induk yang ditetapkanSIGPIPE
untuk diabaikan, tidak mungkin bagi proses anak untuk membatalkannya lagi dalam cangkang non-interacitive.Namun, adalah mungkin untuk membunuh
type rvm
ketikahead -1
berakhir dengan menggunakan subkulit eksplisit. Dengan cara ini kita bisa latar belakangtype rvm
, kirimtypepid
kehead -1
subkulit dan kemudian menerapkan perangkap diEXIT
sana untuk membunuhtype rvm
secara eksplisit.sumber
type
dapatkan cukup waktu untuk memperhatikan penulisan yang gagal, terjemahkan kode kesalahan dan bahkan cetak pesan kesalahan ke stderr sebelum dibunuh oleh SIGPIPE . Saya pikir solusi Anda tidak mencegah proses produsen (ditype
sini) bereaksi terhadap penulisan yang gagal (karena pipa yang ditutup), bukan?