Что происходит при передаче `yes` другой команде?

Что происходит при передаче `yes` другой команде?

Если yesкоманда выводит "y" непрерывно, пока не будет убита, то она никогда не будет выполнена правильно? Если она никогда не будет выполнена, то как она передает свой вывод следующей команде??

решение1

Программа yesбудет писать в канал, одновременно с считывателем. Если канал пуст, считыватель заблокируется в ядре в вызове read()ожидания большего ввода. Если канал заполнен, запись заблокируется в ядре в вызове ожидания, write()пока считыватель освободит некоторое место в канале.

Ядро посылает SIGPIPEсигнал процессу, если он связывается с записью в канал, у которого нет читателя. Когда процесс чтения закрывает конец чтения канала (явно или в результате его завершения), в следующий раз, когда процесс записи попытается записать в канал, он получит сигнал SIGPIPE.

Чтобы проиллюстрировать этот момент, рассмотрим эту упрощенную версию программы, yesкоторая печатает непрерывный поток y. Эта программа отличается от yesтем, что она генерирует сообщение при получении сигнала SIGPIPE:

#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;
}

Я могу скомпилировать и запустить программу и увидеть, что она ведет себя следующим образом yes:

$ gcc ex.c -o myes

$ ./myes
y
y
y
...

Если я передам вывод другому процессу, то после завершения этого процесса (и закрытия считывающего конца канала) программа myesполучит SIGPIPEсигнал (о чем свидетельствует соответствующее сообщение).

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

Связанный контент