Cosa fa morire un processo Unix con Broken pipe?


30

Ecco alcune opzioni a cui ho pensato, non sono sicuro di quale sia quella giusta.

  1. Si è verificato un errore I / O durante la lettura dalla pipe.
  2. Il processo di scrittura sull'altra estremità della pipe si è interrotto con un errore.
  3. Tutti i processi che potrebbero scrivere sulla pipe lo hanno chiuso.
  4. Il buffer di scrittura della pipe è pieno.
  5. Il peer ha chiuso l'altra direzione del tubo duplex.
  6. La scrittura non è riuscita perché non ci sono processi in grado di leggere dalla pipe.
  7. Una chiamata di sistema ha restituito l'errore EPIPE e non è stato installato alcun gestore errori.

Qual'è la tua domanda? Stai chiedendo quale di questi è corretto o se ci sono altre cose che possono causare il tubo rotto?
EightBitTony,

@EightBitTony Quale di questi è corretto
siamii,

Risposte:


38

Un processo riceve un SIGPIPE quando tenta di scrivere su una pipe (denominata o no) o su un socket di tipo SOCK_STREAM a cui non è rimasto alcun lettore.

In genere è un comportamento ricercato. Un esempio tipico è:

find . | head -n 1

Non si desidera findcontinuare a funzionare una volta headterminato (e quindi chiuso l'unico descrittore di file aperto per la lettura su quella pipe).

Il yescomando si basa in genere su quel segnale per terminare.

yes | some-command

Scriverà "y" fino a quando un comando non termina.

Nota che non è solo quando i comandi escono, è quando tutti i lettori hanno chiuso la loro lettura fd sulla pipe. Nel:

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

Ci sarà 1 (la subshell), quindi 2 (subshell + sleep), quindi 1 (subshell) quindi 0 fd che legge dalla pipe dopo che la subshell chiude esplicitamente il suo stdin, ed è allora yesche riceverà un SIGPIPE.

Sopra, la maggior parte delle shell usa a pipe(2) po ' ksh93usa a socketpair(2), ma il comportamento è lo stesso in questo senso.

Quando un processo ignora il SIGPIPE, la chiamata di sistema di scrittura (in genere write, ma potrebbe essere pwrite, send, splice...) ritorna con un EPIPEerrore. Quindi i processi che vogliono gestire manualmente il tubo rotto in genere ignorano SIGPIPE e agiscono in caso di errore EPIPE.


14

(6)

La scrittura non è riuscita perché non ci sono processi in grado di leggere dalla pipe.

Sebbene a meno che non si duplicino descrittori e fork, ci può essere solo un processo con cui iniziare: generalmente una pipe ha un lettore e un writer e quando uno di essi chiude la connessione, la pipe è defunta. Se si utilizza una pipe denominata, è possibile effettuare più connessioni (in serie) con essa, ma ognuna rappresenta una nuova pipe in questo senso. Quindi una "pipe" per un thread o un processo è sinonimo di un descrittore di file.

Da man 7 pipe:

Se tutti i descrittori di file che si riferiscono all'estremità di lettura di una pipe sono stati chiusi, allora una scrittura (2) genererà un segnale SIGPIPE per il processo di chiamata. Se il processo di chiamata ignora questo segnale, la scrittura (2) fallisce con l'errore EPIPE.

Quindi un "tubo rotto" è per lo scrittore ciò che EOF è per il lettore.


0

Una pipe rotta si verifica quando il processo di lettura termina prima del processo di scrittura. Quindi vorrei andare con (6)


2
Possono esserci diversi processi di lettura o scrittura su una pipe e lo stesso processo può essere di lettura e scrittura. Inoltre, non si tratta di uscire, si tratta di chiudere il descrittore di file.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.