다른 명령에 "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

관련 정보