如果我想通过客户端(在 OpenWrt 10.04 路由器上)tcpdump DNS 请求,那么我
root@ROUTER:/etc# tcpdump -n -i br-lan dst port 53 2>&1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), capture size 96 bytes
22:29:38.989412 IP 192.168.1.200.55919 > 192.168.1.1.53: 5697+ A? foo.org. (25)
22:29:39.538981 IP 192.168.1.200.60071 > 192.168.1.1.53: 17481+ PTR? 150.33.87.208.in-addr.arpa. (44)
^C
2 packets captured
3 packets received by filter
0 packets dropped by kernel
完全没问题。但。为什么我无法实时传输 tcpdumps 输出?
root@ROUTER:/etc# tcpdump -n -i br-lan dst port 53 2>&1 | awk '/\?/ {print $3}'
^C
root@ROUTER:/etc#
如果我在 tcpdump 之后执行 awk 等任何操作,我不会得到任何输出。这是为什么?为什么我无法通过管道实时处理 tcpdump 的输出? (例如:在示例中仅输出第三列)
有什么解决办法吗?
答案1
直接出man tcpdump
-l Make stdout line buffered. Useful if you want to see the data while
capturing it. E.g.,
tcpdump -l | tee dat
or
tcpdump -l > dat & tail -f dat
Note that on Windows,``line buffered'' means ``unbuffered'', so that
WinDump will write each character individually if -l is specified.
-U is similar to -l in its behavior, but it will cause output to be
``packet-buffered'', so that the output is written to stdout at the
end of each packet rather than at the end of each line; this is
buffered on all platforms, including Windows.
答案2
-U
结合使用该选项-w
,以便 tcpdump 立即写入数据包。
答案3
tcpdump 在写入管道时显然正在缓冲输出。它不会刷新每次写入的输出,因此系统将以大约 4k 字节块的形式写入输出。您的过滤器限制了输出,因此在该过滤器写入足够的输出之前您不会看到任何内容。一旦收集到足够的数据,它将被写成一个块,然后您应该看到发出几行。
尝试多次触发 DNS 查找,看看会发生什么。
答案4
expect
有一个unbuffer
命令可以欺骗命令,使其假设它们正在写入 tty,因此它们不会缓冲。