
명령이 종료될 때까지 계속 "y"를 에코 하면 yes
명령이 절대 완료되지 않습니다. 결코 완료되지 않으면 출력을 다음 명령으로 어떻게 파이프합니까 ??
답변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