Explicação simplificada
Como muitos utilitários, isso não é algo peculiar a um programa, grep
varia sua saída padrão entre linha em buffer e totalmente em buffer . No primeiro caso, a biblioteca C armazena os dados de saída na memória até que o buffer contendo esses dados seja preenchido ou um caractere de alimentação de linha seja adicionado a ele (ou o programa termina de forma limpa), ao que chama write()
para realmente gravar o conteúdo do buffer . No último caso, somente o buffer na memória se tornando cheio (ou o programa terminando de forma limpa) aciona o write()
.
Explicação mais detalhada
Esta é a explicação bem conhecida, mas ligeiramente errada. Na verdade, a saída padrão não é armazenada em buffer de linha, mas smart buffered na biblioteca GNU C e na biblioteca BSD C. A saída padrão é também liberada quando a leitura da entrada padrão esgota seu buffer na memória (da entrada pré-leitura) e a biblioteca C precisa chamar read()
para buscar mais alguma entrada e está lendo o começo de uma nova linha. (Um motivo para isso é impedir o deadlock quando outro programa se conecta a ambas as extremidades de um filtro e espera poder operar linha por linha, alternando entre gravar no filtro e ler a partir dele, como "coprocessos" no GNU awk
por exemplo.
Influência da biblioteca C
grep
e os outros utilitários fazem isso - ou, mais estritamente, as bibliotecas C que eles usam fazem isso, porque esse é um recurso definido de programação na linguagem C - baseado no que eles detectam sua saída padrão. . Se (e somente se) não for um dispositivo interativo, eles escolhem o buffer completo, caso contrário, eles escolhem o armazenamento em buffer inteligente. Um pipe é considerado não como um dispositivo interativo, porque a definição de ser um dispositivo interativo, pelo menos no mundo do Unix e do Linux, é essencialmente a chamada isatty()
que retorna true para o descritor de arquivo relevante.
Soluções alternativas para desativar o buffer completo
Alguns utilitários como grep
têm opções idiossincráticas, como --line-buffered
, que alteram essa decisão, o que, como você pode ver, é mal-nomeado. Mas uma fração extremamente pequena dos programas de filtragem que se pode usar realmente tem essa opção.
Em geral, é possível usar ferramentas que acessam os recursos internos específicos da biblioteca C e alteram sua tomada de decisão (que tem problemas de segurança se o programa a ser alterado for set-UID e também específico para determinadas bibliotecas C, e, de fato, são específicos para programas escritos em camadas ou em cima da linguagem C), ou ferramentas como ptybandage
que não alteram os componentes internos do programa, mas simplesmente interpõem um pseudo-terminal como padrão saída para que a decisão saia como "interativa", para afetar isso.
Leitura adicional