¿Qué sucede cuando se transmite el "sí" a otro comando?

¿Qué sucede cuando se transmite el "sí" a otro comando?

Si el yescomando 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 yesprograma 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 SIGPIPEseñ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 SIGPIPEseñal.

Para ilustrar este punto, considere esta versión simplificada del yesprograma que imprime un flujo continuo de archivos y. Este programa se diferencia yesen que genera un mensaje cuando recibe la SIGPIPEseñ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 myesprograma recibe la SIGPIPEseñal (como lo indica el mensaje asociado).

$ ./myes | head -n5
y
y
y
y
y
received SIGPIPE signal, terminating

información relacionada