Filtrado de salida de tcpdump y ejecución de script cuando se encuentra una cadena en tiempo real

Filtrado de salida de tcpdump y ejecución de script cuando se encuentra una cadena en tiempo real

Tengo este comando que muestra los paquetes recibidos y enviados en el puerto 1700.

tcpdump -AUq puerto 1700

En el paquete está la cadena rxpk, pero la mayoría de los paquetes no la tienen. Cuando la salida contiene esta cadena, quiero que se ejecute algún script (que haga parpadear un LED).

tcpdump -AUq port 1700 | awk '/rxpk/ { print | "/path/to/blink_led 18" }'

Pero parece que solo coincide la primera vez que rxpkse encuentra an, las apariciones posteriores no activarán la { ... }parte -

¿Alguien tiene una idea de por qué? ¿O incluso otro método para ejecutar un script cuando rxpkse recibe?

Respuesta1

La razón por la que el LED parpadea solo una vez es que cuando imprime en una tubería, la tubería permanece abierta, por lo que solo hay una invocación de blink_led. Si blink_ledleyera su entrada estándar para obtener instrucciones, entonces esto no sería un problema. Si no puede leer la entrada estándar y sale, awktambién saldrá.

La forma convencional de evitar esto es utilizar close()la tubería para que la siguiente invocación inicie una nueva:

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

system()también está bien, como lo sugiere @heemayl (y probablemente mejor si blink_ledno tiene ningún interés en leer stdin).

Notarás que estoy usando -len lugar de -U, -lvacía stdout para evitar pausas si la salida que deseas está esperando en un buffer stdio ( -Uhabilita el vaciado de paquetes completos cuando usas -wpara escribir en un archivo).

información relacionada