Comment un pipeline sait-il quand arrêter

Certains programmes peuvent avoir un time d'exécution infini et produire une sortie infinie. Lorsqu'il est utilisé dans un tuyau avec une command qui se termine, comment le pipeline sait-il quand s'arrêter?

Par exemple, prenez yes (sortie infinie) avec la head :

  yes | head -n 5 

Il ne donnera que 5 ans.

La première command termine-t-elle celle qui arrête les autres process d'input / sortie?
Comment ça fonctionne ?

Les commands sont connectées à un pipe (je parle ici de la primitive système – évidemment, elles sont connectées à un | ). Lorsque l'extrémité lue du tube (le stdin de la head ) devient close d (== quand la head close explicitement ou implicitement (exit) le ferme), les tentatives d'écrire à la fin d'écriture ( stdout de yes ) échouent.

Par défaut, il ne s'agit pas simplement d'une erreur errno régulière, mais d'un échec qui entraîne l'écriture du signal SIGPIPE . L'action de gestionnaire par défaut du signal SIGPIPE doit se terminer.

En bref, si vous écrivez à un tuyau brisé, le système vous enverra un SIGPIPE et, par défaut, un SIGPIPE vous tuera. C'est pourquoi yes termine lorsque la head est terminée (et ainsi cassé le tuyau).


Si vous ignorez SIGPIPE dans le shell parent, les commands hériteront de cette disposition et une write sur un canal brisé entraînera simplement une erreur d'erreur d' EPIPE . Comme il apparaît, yes ssortingngifie cette erreur et l'imprime:

 $ (trap "" SIGPIPE; yes | head -n 5) y y y y yes: standard output: Broken pipe yes: write error