Pipe
將“是”傳遞給另一個命令時會發生什麼?
如果
yes
命令連續回顯“y”直到被殺死,那麼它永遠不會完成對嗎?如果它永遠不會完成,那麼它如何將它的輸出傳遞給下一個命令?
該
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