实时找到字符串时过滤 tcpdump 的输出并运行脚本

实时找到字符串时过滤 tcpdump 的输出并运行脚本

我有这个命令显示端口 1700 上接收和发送的数据包。

tcpdump -AUq 端口 1700

数据包中有字符串rxpk,但大多数数据包没有它。当输出包含此字符串时,我希望运行一些脚本(闪烁 LED)。

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

但似乎它只在第一次rxpk找到时匹配,后续发生的情况不会触发{ ... }- 部分

有人知道为什么吗?或者甚至是在rxpk收到脚本时运行脚本的其他方法?

答案1

LED 仅闪烁一次的原因是,当您打印到管道时,该管道保持打开状态,因此只有一次 的调用blink_led。如果blink_led要读取其标准输入以获取说明,那么这不会是问题。如果它无法读取 stdin 并退出,那么awk也会退出。

解决这个问题的传统方法是使用close()管道,以便下一次调用启动一个新的:

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

system()也很好,正如 @heemayl 所建议的(如果blink_led根本没有兴趣阅读 stdin,可能会更好)。

您会注意到,如果您想要的输出在 stdio 缓冲区中等待,我使用-l而不是刷新 stdout 来避免暂停(当您用于写入文件时启用整个数据包刷新)。-U-l-U-w

相关内容