O Grep falha em sair do pipe?

2

Estou tendo problemas com a filtragem do grep do make output. Em particular,

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

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

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

Estou sentindo falta de algo óbvio? Por que o primeiro comando é gerado, mas não o segundo? Tem a ver com algum tipo de buffer de E / S? Ou eu estou apenas sendo idiota?

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

[EDIT]: Isso não parece ser um problema com o grep, pois substituí-lo por ack para o mesmo comportamento.

[EDITAR]: Script em que o gato é um marcador 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. Eu estou deixando a compilação passando por cima da w / e e verei se ela eventualmente recebe a saída onde ela precisa!

    
por brice 03.02.2012 / 18:10

3 respostas

5

Provável grep está detectando que não está gravando em um TTY, então ele armazena mais saída, em vez de operar em seu modo usual de buffer de linha (ou seja, você vê cada linha conforme ela é encontrada). Esse comportamento é mais eficiente, pois resulta em menos write() de chamadas do sistema, mas se você for um usuário que está esperando por uma saída com pipelining, isso pode ser um pouco enganoso.

Se você estiver usando o GNU grep (e com base na sua tag linux, suponho que você esteja), confira a opção --line-buffered , que forçará grep a trabalhar no modo buffer de linha mais familiar . Isso pode reduzir tecnicamente o desempenho de grep (como observado na man page), mas como você está vendo a saída de uma compilação ao vivo, duvido que faça alguma diferença a esse respeito.

    
por 04.02.2012 / 07:57
1

Não tem certeza do que seu comando deve fazer, catar qualquer arquivo que tenha criado. * em seu nome de arquivo?

Tente alterar o cat para xargs cat ?

    
por 03.02.2012 / 18:15
1

Você pode experimentar com unbuffer , por exemplo,

make target 2>&1 | unbuffer -p grep -E --color=never "^make.*" | cat
    
por 03.02.2012 / 19:02