
Se o yes
comando ecoar "y" continuamente até ser morto, isso nunca será feito, certo? Se isso nunca for feito, como ele canaliza a saída para o próximo comando?
Responder1
O yes
programa irá escrever no pipe, simultaneamente com o leitor. Se o pipe estiver vazio, o leitor bloqueará o kernel em uma chamada para read()
aguardar mais entradas. Se o canal estiver cheio, a gravação será bloqueada no kernel em uma chamada para write()
aguardar que o leitor libere espaço no canal.
O kernel fornece um SIGPIPE
sinal para um processo se ele estiver vinculado à gravação em um canal que não possui leitor. Quando o processo de leitura fecha a extremidade de leitura do tubo (explicitamente ou como resultado de seu término), na próxima vez que o processo de escrita tentar escrever no tubo, ele receberá o SIGPIPE
sinal.
Para ilustrar este ponto, considere esta versão simplificada do yes
programa que imprime um fluxo contínuo de y
. Este programa difere yes
porque gera uma mensagem ao receber o SIGPIPE
sinal:
#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;
}
Posso compilar e executar o programa e ver se ele se comporta como yes
:
$ gcc ex.c -o myes
$ ./myes
y
y
y
...
Se eu canalizar a saída para outro processo, quando esse processo terminar (e a extremidade de leitura do canal for fechada), o myes
programa receberá o SIGPIPE
sinal (conforme indicado pela mensagem associada).
$ ./myes | head -n5
y
y
y
y
y
received SIGPIPE signal, terminating