Para eficiência, grep e muitos outros comandos usam buffered I / O , isto é, eles lêem grandes blocos de dados de uma vez (ao invés de, digamos, um caractere de cada vez), e fazem não produza dados até que uma certa quantidade tenha sido acumulada (em vez de, digamos, escrever uma linha por vez ou um caractere de cada vez)
Mas, quando a entrada de um programa é de um terminal (como sua porta serial), o sistema operacional favorece o programa e retorna uma linha por vez (o programa pode mudar isso colocando o terminal em raw ou modo não-canônico a maioria não aceita.
E quando um programa usa a biblioteca stdio , a saída padrão para um terminal (a documentação chama isso de "dispositivo interativo") é, por padrão, line buffered, mas a saída para um arquivo ou pipe é totalmente armazenada em buffer.
Um programa que usa a biblioteca stdio pode escolher buffering completo, buffer de linha ou nenhum buffer chamando setvbuf
. Ele também pode chamar fflush
para forçar uma gravação sempre que desejar.
O GNU grep tem uma opção --line-buffered
, que executará o o seguinte código na função que gera uma linha correspondente:
if (line_buffered)
fflush (stdout);
Colocando todas as peças juntas:
Com este comando:
cat /dev/ttyACM0 | grep "something" > essai
cat
lerá uma linha por vez a partir de /dev/ttyACM0
. Depois de acumular alguns kilobytes de saída, ele gravará no pipe. Ele irá repetir isso até a leitura retornar uma contagem de zero ou falha (o que provavelmente não acontecerá até que a porta serial fique offline).
grep
lerá alguns kilobytes por vez do pipe e, depois de acumular alguns kilobytes de saída, gravará no essai
fle. Ele repetirá isso até que a leitura retorne uma contagem de zero ou falha, o que acontecerá se e quando o processo cat
terminar.
Assim, você não verá nada no arquivo essai
até que grep
encontre alguns kilobytes de linhas correspondentes.
Para obter a saída gravada no arquivo mais rapidamente, você pode dar ao GNU grep essa opção:
grep --line-buffered < /dev/ttyACM0 > essai
Como ele está lendo de uma porta serial, ele será armazenado em buffer de linha e a opção --line-buffered
também fará com que a linha de saída seja armazenada em buffer.