Grep não consegue sair para um cano?

Grep não consegue sair para um cano?

Estou tendo problemas com a filtragem grep da saída do make. Em particular,

make target 2>&1 | grep -E --color=never "^make.*"

funciona conforme o esperado, mas o seguinte não imprimirá nenhuma saída no console:

make target 2>&1 | grep -E --color=never "^make.*" | cat

Estou perdendo algo óbvio? Por que o primeiro comando é gerado, mas não o segundo? Tem a ver com algum tipo de buffer de IO? Ou estou apenas sendo estúpido?

[EDITAR]: caté apenas um espaço reservado mínimo de caso de teste para o comando real que desejo usar.

[EDITAR]:Isto não parece ser um problema com o grep, pois substituí-lo porackleva ao mesmo comportamento.

[EDITAR]:Script para o qual cat é um espaço reservado para:

#!/bin/bash
cat - \
 | grep -E --color=never "^.*warning:.*|^.*error:.*|^make.*[Ee]rror.*|^make.*" \
 | hilite.sh -r "^.*warning:.*" -f yellow -B \
 | hilite.sh -r "^.*error:.*" -f red -B \
 | hilite.sh -r "^make.*[Ee]rror.*" -f red -B \
 | hilite.sh -r "^make.*" -f magenta

[EDITAR]:Acho que é um problema de buffer/IO. Estou deixando a compilação em execução e verei se ela eventualmente obtém a saída onde precisa!

Responder1

Provavelmente grepestá detectando que ele não está gravando em um TTY, portanto ele armazena mais saída em buffer, em vez de operar em seu modo de buffer de linha normal (ou seja, você vê cada linha conforme é encontrada). Esse comportamento é mais eficiente, pois resulta em menos write()chamadas de sistema, mas se você for um usuário que está aguardando a saída do pipeline, poderá ser um pouco enganador.

Se você estiver usando GNU grep(e com base na sua tag linux, presumo que você esteja), verifique a --line-bufferedopção, que forçará grepo trabalho no modo de buffer de linha mais familiar. Tecnicamente, isso poderia diminuir o desempenho grep(conforme observado na página de manual), mas como você está olhando o resultado de uma compilação ao vivo, duvido que faça alguma diferença nesse aspecto.

Responder2

Não tem certeza do que seu comando deve fazer, cat quaisquer arquivos que tenham make.* em seu nome de arquivo?

Tente mudar o catfor xargs cat?

Responder3

Você pode tentar experimentar unbuffer, por exemplo,

make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat

informação relacionada