Você deve usar grep --line-buffered percentage
ou então levará um tempo muito longo para que o buffer grep
stdout seja preenchido por sua saída.
O seguinte não produz nada no bash:
while true ; do upower -d ; sleep 1 ; done | grep percentage | uniq
Descobri que não importa qual seja o último ou o segundo até o último programa nessa cadeia. O penúltimo programa sempre produz a saída esperada, e o último sempre falha em produzir qualquer coisa.
Também não parece importar se eu envolver o loop while em um subshell (via ( while ... done )
), ou envolver tudo menos o último comando em uma subshell e canalizar para o último comando.
Estou profundamente confuso com esse comportamento.
... que há algum tipo de travamento de E / S na cadeia criada pelo bloqueio de leituras e gravações e o fato de que o loop while não está sempre produzindo saída. Mas, por outro lado, já fiz esse tipo de coisa muitas vezes antes, sem nenhum problema. Além disso, se fosse assim, o problema não existiria entre o loop while e o próximo comando? Então estou perplexa. Fornecerá informações da versão bash se ninguém mais puder reproduzir.
O objetivo desta linha de código é imprimir todas as alterações na porcentagem de bateria, mas somente imprimir novos níveis de bateria. Usa polling. Eu suponho que eu poderia ter o mesmo comportamento simplesmente executando
upower --monitor-detail | grep percentage | uniq
Mas isso é uma coisa única, e eu não planejava gastar mais do que 5 segundos pensando nisso até que o acima começou a falhar. Nesse ponto, tornou-se um problema interessante. Além disso, eu não sei se o detalhe do monitor apenas faz polling sob o capô, de qualquer forma (e eu não estou correndo um strace para verificar).
EDIT: Aparentemente, a versão --monitor-detail
acima também não produz nada (ou, pelo menos, parece. A frequência de sondagem / atualização é muito baixa, então eu poderia não esperei o tempo suficiente, embora eu saiba que esperei o tempo suficiente para a edição original). Agora estou muito confuso. Eu acho que eu deveria correr essa linha depois de tudo ...
Além da resposta de Marco d'Itri, nem todas as ferramentas suportam o armazenamento em buffer personalizado. Caso a ferramenta que você está executando não tenha, ou caso você queira executá-la usando um tamanho de buffer personalizado, você pode usar stdbuf
para substituir o comportamento de buffer da ferramenta; neste caso, por exemplo, para forçar a saída a ser armazenada em buffer:
while true ; do upower -d ; sleep 1 ; done | stdbuf -oL grep 'percentage' | uniq
Para forçar a saída a ser unbuffered:
while true ; do upower -d ; sleep 1 ; done | stdbuf -o0 grep 'percentage' | uniq
Para forçar a saída para buffer em blocos de 512 B:
while true ; do upower -d ; sleep 1 ; done | stdbuf -o512 grep 'percentage' | uniq
Você pode adicionar K, M, G, [...] para especificar a saída em KB, MB, GB, [...]:
while true ; do upower -d ; sleep 1 ; done | stdbuf -o512K grep 'percentage' | uniq
Com qualquer POSIX sed
, você pode obter a saída com buffer de linha com o comando w
rite.
while sleep 1
do upower -d
done |
sed -n /percentage/w\ /dev/fd/1 |
uniq
... funcionará em sistemas que suportam os /dev/fd/[num]
links (como praticamente qualquer sistema linux).
Mas você poderia fazer:
while sleep 1
do upower -d
done |
sed '/percentage/!d;H;x
/^\(.*\)\n$/d;g'
O texto acima deve funcionar em vez disso - apenas agrupa as funções de uniq
e grep
em um único script sed
.