Filtern der Ausgabe von tcpdump und Ausführen des Skripts, wenn eine Zeichenfolge in Echtzeit gefunden wird

Filtern der Ausgabe von tcpdump und Ausführen des Skripts, wenn eine Zeichenfolge in Echtzeit gefunden wird

Ich habe diesen Befehl, der auf Port 1700 empfangene und gesendete Pakete anzeigt.

tcpdump -AUq Port 1700

Im Paket befindet sich die Zeichenfolge rxpk, aber die meisten Pakete haben sie nicht. Wenn die Ausgabe diese Zeichenfolge enthält, möchte ich, dass ein Skript (das eine LED blinken lässt) ausgeführt wird.

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

Aber es scheint, dass es nur beim ersten Mal übereinstimmt, wenn ein rxpkgefunden wird, nachfolgende Vorkommen lösen den { ... }-Teil nicht aus

Hat jemand eine Idee, warum? Oder sogar einen anderen Ansatz, um ein Skript auszuführen, wenn rxpkes empfangen wird?

Antwort1

Der Grund, warum die LED nur einmal blinkt, ist, dass beim Drucken in eine Pipe die Pipe geöffnet bleibt, sodass nur ein Aufruf von erfolgt blink_led. Wenn blink_leddie Standardeingabe für Anweisungen gelesen werden soll, wäre dies kein Problem. Wenn das Lesen der Standardeingabe fehlschlägt und beendet wird, awkwird auch beendet.

Der herkömmliche Weg, dies zu umgehen, besteht darin, close()die Pipe so zu verwenden, dass der nächste Aufruf einen neuen startet:

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

system()ist auch in Ordnung, wie von @heemayl vorgeschlagen (und wahrscheinlich besser, wenn blink_ledüberhaupt kein Interesse daran besteht, stdin zu lesen).

Sie werden feststellen , dass ich -lanstelle von verwende . Die Standardausgabe wird geleert, um Pausen zu vermeiden, wenn die gewünschte Ausgabe in einem Standarddio-Puffer wartet ( aktiviert das Leeren ganzer Pakete, wenn Sie zum Schreiben in eine Datei verwenden).-U-l-U-w

verwandte Informationen