
Eu tenho este comando que exibe os pacotes recebidos e enviados na porta 1700.
tcpdump -AUq porta 1700
No pacote existe a string rxpk
, mas a maioria dos pacotes não a possui. Quando a saída contém essa string, quero que algum script (que pisca um led) seja executado.
tcpdump -AUq port 1700 | awk '/rxpk/ { print | "/path/to/blink_led 18" }'
Mas parece que ele corresponde apenas à primeira vez que an rxpk
é encontrado, as ocorrências subsequentes não acionarão o { ... }
-part
Alguém tem ideia do porquê? Ou mesmo uma outra abordagem para executar um script quando rxpk
for recebido?
Responder1
A razão pela qual o LED pisca apenas uma vez é que quando você imprime em um canal, o canal permanece aberto, portanto há apenas uma invocação de blink_led
. Se blink_led
fosse ler seu stdin para obter instruções, isso não seria um problema. Se não conseguir ler stdin e sair, então awk
sairá também.
A maneira convencional de contornar isso é usar close()
o pipe para que a próxima invocação inicie uma nova:
tcpdump -Alq port 1700 | awk '
BEGIN { mypipe="/path/to/blink_led 18"; }
/rxpk/ { print | mypipe; close(mypipe); }'
system()
também está bom, como sugerido por @heemayl (e provavelmente melhor se blink_led
não tiver nenhum interesse em ler stdin).
Você notará que estou usando -l
em vez de -U
, -l
libera stdout para evitar pausas se a saída desejada estiver aguardando em um buffer stdio ( -U
permite a liberação de todo o pacote quando você usa -w
para gravar em um arquivo).