Apa yang membuat proses Unix mati dengan pipa Rusak?

30

Berikut adalah beberapa opsi yang saya pikirkan, tidak yakin mana yang benar.

  1. Ada kesalahan I / O membaca dari pipa.
  2. Proses penulisan ke ujung pipa yang lain mati dengan kegagalan.
  3. Semua proses yang bisa menulis ke pipa telah menutupnya.
  4. Buffer tulis dari pipa sudah penuh.
  5. Rekan telah menutup arah lain dari pipa dupleks.
  6. Penulisan gagal karena tidak ada proses yang dapat membaca dari pipa.
  7. Panggilan sistem mengembalikan kesalahan EPIPE, dan tidak ada penangan kesalahan yang diinstal.
siamii
sumber
Apa pertanyaanmu? Apakah Anda bertanya yang mana yang benar, atau apakah ada hal lain yang dapat menyebabkan pipa rusak?
EightBitTony
@EightBitTony Manakah dari ini yang benar
siamii

Jawaban:

38

Suatu proses menerima SIGPIPE ketika mencoba untuk menulis ke pipa (bernama atau tidak) atau soket tipe SOCK_STREAM yang tidak memiliki pembaca tersisa.

Itu umumnya perilaku yang diinginkan. Contoh khas adalah:

find . | head -n 1

Anda tidak ingin findterus berjalan setelah headdiakhiri (dan kemudian tutup satu-satunya deskriptor file yang terbuka untuk dibaca pada pipa itu).

The yesperintah biasanya bergantung pada sinyal untuk mengakhiri.

yes | some-command

Akan menulis "y" sampai beberapa perintah berakhir.

Perhatikan bahwa bukan hanya ketika perintah keluar, itu ketika semua pembaca telah menutup bacaan fd ke pipa. Di:

yes | ( sleep 1; exec <&-; ps -fC yes)
      1 2       1        0

Akan ada 1 (subkulit), kemudian 2 (subkulit + tidur), lalu 1 (subkulit) lalu 0 fd membaca dari pipa setelah subkulit secara eksplisit menutup stdinnya, dan saat itulah yesakan menerima SIGPIPE.

Di atas, sebagian besar cangkang menggunakan pipe(2)sementara ksh93menggunakan a socketpair(2), tetapi perilakunya sama dalam hal itu.

Ketika proses mengabaikan SIGPIPE, panggilan sistem penulisan (umumnya write, tapi bisa pwrite, send, splice...) kembali dengan EPIPEkesalahan. Jadi proses yang ingin menangani pipa yang rusak secara manual biasanya akan mengabaikan SIGPIPE dan mengambil tindakan atas kesalahan EPIPE.

Stéphane Chazelas
sumber
14

(6)

Penulisan gagal karena tidak ada proses yang dapat membaca dari pipa.

Meskipun kecuali jika Anda menduplikasi deskriptor dan fork, hanya ada satu proses untuk memulainya: umumnya sebuah pipa memiliki satu pembaca dan satu penulis, dan ketika salah satu dari mereka menutup koneksi, pipa tersebut tidak berfungsi. Jika Anda menggunakan pipa bernama, Anda dapat membuat beberapa koneksi (secara serial) dengannya, tetapi masing-masing mewakili pipa baru dalam pengertian ini. Jadi "pipa" ke utas atau proses identik dengan deskriptor file.

Dari man 7 pipe:

Jika semua deskriptor file yang merujuk ke ujung baca dari sebuah pipa telah ditutup, maka penulisan (2) akan menyebabkan sinyal SIGPIPE dihasilkan untuk proses pemanggilan. Jika proses panggilan mengabaikan sinyal ini, maka tulis (2) gagal dengan EPIPE kesalahan.

Jadi "pipa yang putus" bagi penulis sama seperti EOF bagi pembaca.

goldilocks
sumber
0

Pipa yang rusak terjadi ketika proses membaca keluar sebelum proses penulisan. Jadi saya akan pergi dengan (6)

SidJ
sumber
2
Mungkin ada beberapa proses membaca atau menulis ke pipa, dan proses yang sama dapat membaca dan menulis. Juga, ini bukan tentang keluar, ini tentang menutup deskriptor file.
Stéphane Chazelas