¿Cómo es que `si bien es cierto; hacer eco y; hecho | true` muere por sí solo, pero `mientras sea true; hacer eco y | gato; hecho | cierto`¿no?

¿Cómo es que `si bien es cierto; hacer eco y; hecho | true` muere por sí solo, pero `mientras sea true; hacer eco y | gato; hecho | cierto`¿no?

Para ser claro con la pregunta del título, entiendo por qué muere el primero. No entiendo por qué este último no lo hace, solo por agregar un | catal cuerpo del bucle.

También tal vez relacionado,

while true; do echo y; done

muere inmediatamente cuando lo hago ^C, pero matando

while true; do echo y | cat; done

A menudo es necesario golpearlo ^Cmás de una vez. A veces funciona una vez, otras veces funciona 2 o 3 veces, luego hay momentos en los que necesito aguantar ^Cun rato para que muera.

Ambos comportamientos ocurren tanto en bash como en zsh, aunque ^Cuno parece ser más raro con bash.

Para ambos comportamientos, esto no se limita a agregar la tubería a cat. | dd, | tee, etc. también los causan. Incluso echo y | truelo provoca. Parece ser la presencia de algún tubo en el cuerpo del bucle.

¿Por qué la presencia de una tubería en el cuerpo de un bucle cambia la respuesta del bucle a las señales?

Respuesta1

En while true; do echo y; done | true, como echoestá integrado, tienes un proceso de subcapa que escribe y\nen un bucle en una tubería.

Cuando trueregresa, el extremo de lectura de esa tubería se cierra, por lo que escribir en el extremo de escritura hace que se SIGPIPEentregue a al proceso de escritura. Aquí, ese es el proceso de subcapa que ejecuta el ciclo.

En while true; do echo y | cat; done | true, es catel que escribe en la tubería. catgeneralmente no está integrado, e incluso si lo estuviera, en shells distintos de zsh y ksh, todos los componentes de tuberías siempre se ejecutan en procesos secundarios.

Entonces, aquí solo el proceso en ejecución catmuere y el proceso de subcapa que ejecuta el bucle continúa ejecutando más catprocesos que mueren tan pronto como escriben y\nen su salida estándar.

En ksh93/ksh2020, si lo hace:

$ builtin cat
$ type cat
cat is a shell builtin
$ set -o pipefail
$ while true; do echo y | cat; done | true; kill -l "$?"
PIPE

Esta vez, catestá integrado y se ejecuta en el mismo proceso que el bucle (al igual que catel comando más a la derecha en la primera línea de canalización y ksh no lo ejecuta en un subshell), por lo que el subshell sale truey kill -lconfirma que fue asesinado por un SIGPIPE.

información relacionada