
Si el yes
comando repite "y" continuamente hasta que se elimina, entonces nunca se ejecutará, ¿verdad? Si nunca se hace, ¿cómo canaliza su salida al siguiente comando?
Respuesta1
El yes
programa escribirá en la tubería al mismo tiempo que el lector. Si la tubería está vacía, el lector bloqueará el kernel en una llamada para read()
esperar más entradas. Si la tubería está llena, la escritura se bloqueará en el kernel en una llamada a la write()
espera de que el lector libere algo de espacio en la tubería.
El kernel entrega una SIGPIPE
señal a un proceso si se vincula para escribir en una tubería que no tiene lector. Cuando el proceso de lectura cierra el extremo de lectura de la tubería (ya sea explícitamente o como resultado de su terminación), la próxima vez que el proceso de escritura intente escribir en la tubería, recibirá la SIGPIPE
señal.
Para ilustrar este punto, considere esta versión simplificada del yes
programa que imprime un flujo continuo de archivos y
. Este programa se diferencia yes
en que genera un mensaje cuando recibe la SIGPIPE
señal:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
static void handler(int sig) {
#define msg "received SIGPIPE signal, terminating\n"
write(2, msg, sizeof msg);
exit(1);
#undef msg
}
int main(void) {
// Instruct the kernel to call the handler() function when
// this process receives the SIGPIPE signal. The default behavior
// when this signal is received is for the process to terminate.
signal(SIGPIPE, handler);
for (;;) {
if (write(1, "y\n", 2) < 0) {
fprintf(stderr, "%s\n", strerror(errno));
return 2;
}
}
return 0;
}
Puedo compilar y ejecutar el programa y ver que se comporta así yes
:
$ gcc ex.c -o myes
$ ./myes
y
y
y
...
Si canalizo la salida a otro proceso, cuando ese proceso termina (y el extremo de lectura de la tubería se cierra), el myes
programa recibe la SIGPIPE
señal (como lo indica el mensaje asociado).
$ ./myes | head -n5
y
y
y
y
y
received SIGPIPE signal, terminating