Os dados em um pipe só podem ser lidos uma vez; a parte "o que é novo" é fácil. Basta criar um pipe nomeado com mkfifo
, redirecionar sua saída inotifywait para ele com >
e ler o pipe periodicamente.
A parte mais complicada é a leitura de um pipe, que está aberto para gravação em algum lugar, sem bloqueio. dd pode fazer isso.
Aqui está a configuração que usei para criar e escrever continuamente em um pipe:
mkfifo foo
( while true ; do date; sleep 1 ; done ) > foo
E para ler todos os dados não lidos:
dd iflag=nonblock if=foo bs=1M count=1 of=buffer.txt
Você pode alterar of=...
para um arquivo de saída de sua escolha.
Mais cedo ou mais tarde, você obterá uma linha parcial do canal, portanto, certifique-se de que seu script possa lidar com isso. Para o tipo de atividade que você descreve, uma boa abordagem é repetir o dd no modo append até que o buffer seja terminado por nova linha:
buf=buffer.txt
pipe=foo
> $buf # empty the buffer
until [[ $( tail -c1 $buf | od -a ) == *nl* ]] # nl means newline
do
dd iflag=nonblock oflag=append conv=notrunc if=$pipe bs=1M count=1 of=$buf
ls -l $buf # see how it grows
sleep 1 # if the writer dies, this loop will be infinite and we don't want to kill the CPU
done
do_stuff.sh < $buf
# rm $buf
EDIT: parece que você quer dizer inotifywait quando você está no terminal e despejar tudo o que é novo. Isso é mais fácil. Faça um arquivo como whatsnew.sh:
#!/bin/bash
echo "waiting for first output ... "
while true
do
n=0
while read -t0.1 line
do
echo "[$line]"
(( n++ ))
done
read -p "$n new lines. Press any key to try again... " -n1 -s </dev/tty
echo
done
Em seguida, inicie:
inotifywait | whatsnew.sh