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