
Tenho uma pergunta fictícia para você: estou tentando extrair algumas linhas de um arquivo começando por uma sequência especial de caracteres e copiá-las para um arquivo. Tentei :
cat /dev/ttyACM0 | grep "something" > essai
O arquivo é criado, mas não contém nada!
Responder1
Para maior eficiência, grep e muitos outros comandos usamE/S armazenada em buffer, isto é, eles leem grandes blocos de dados de uma só vez (em vez de, digamos, um caractere por vez) e não geram dados até que uma certa quantidade tenha sido acumulada (em vez de, digamos, escrever uma linha por vez ou um personagem por vez)
Mas, quando a entrada de um programa vem de um terminal (como sua porta serial), o sistema operacional faz um favor ao programa e retorna uma linha por vez (o programa pode mudar isso colocando o terminal emcruoumodo não canônico; a maioria não).
E quando um programa usa oestúdiobiblioteca, a saída padrão para um terminal (a documentação chama isso de "dispositivo interativo") é, por padrão, armazenada em buffer de linha, mas a saída para um arquivo ou canal é totalmente armazenada em buffer.
Um programa que usa a biblioteca stdio pode escolher buffer completo, buffer de linha ou nenhum buffer chamandosetvbuf
. Também pode ligarfflush
para forçar uma gravação sempre que desejar.
GNU grep leva um--line-buffered
opção, que executará oseguinte códigona função que gera uma linha correspondente:
if (line_buffered)
fflush (stdout);
Juntando todas as peças:
Com este comando:
cat /dev/ttyACM0 | grep "something" > essai
cat
lerá uma linha por vez de /dev/ttyACM0
. Depois de acumular alguns kilobytes de saída, ele gravará no pipe. Ele repetirá isso até que a leitura retorne uma contagem zero ou falhe (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
arquivo. Ele repetirá isso até que a leitura retorne uma contagem zero ou falhe, o que acontecerá se e quando o cat
processo for encerrado.
Portanto, você não verá nada aparecer no essai
arquivo até grep
encontrar 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 está lendo de uma porta serial, ele será armazenado em buffer de linha e a --line-buffered
opção também armazenará a linha de saída em buffer.