Filtrando a saída do tcpdump e executando o script quando a string é encontrada em tempo real

1

Eu tenho este comando que exibe pacotes recebidos e enviados na porta 1700.

tcpdump -porta 1700

No pacote, há a string rxpk , mas a maioria dos pacotes não a possui. Quando a saída contém essa string, eu 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 coincide apenas com a primeira vez que um rxpk é encontrado, ocorrências subseqüentes não acionarão o { ... } -part

Alguém sabe por quê? Ou até mesmo uma outra abordagem para executar um script quando rxpk é recebido?

    
por stUrb 22.09.2016 / 22:37

1 resposta

1

A razão pela qual o LED pisca apenas uma vez é que, quando você imprime em um tubo, o tubo permanece aberto, portanto, há apenas uma invocação de blink_led . Se blink_led leu seu stdin para instruções, isso não seria um problema. Se falhar ao ler stdin e sair, então awk irá sair também.

A maneira convencional em torno disso é close() o pipe, então a próxima invocação começa com uma nova:

tcpdump -Alq port 1700 | awk '
  BEGIN { mypipe="/path/to/blink_led 18"; }
  /rxpk/ { print | mypipe; close(mypipe); }'

system() é bom também, como sugerido por @heemayl (e provavelmente melhor se blink_led não tiver interesse em ler stdin).

Você perceberá 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 ativa a limpeza de pacotes inteiros quando você usa -w para gravar em um arquivo).

    
por 23.09.2016 / 12:01