我实际上想做的是测量 tcpdump 10 秒。
$ timeout 10s tcpdump > my.log
但我发现实际记录的时间很短,而不是整个 10 秒。
因此我做了这个实验:
#!/bin/bash
# a.sh
tcpdump & p1=$!
date
sleep 10s;
echo "Checkpoint #1"
kill $p1;
$ sudo ./a.sh # works as expected
$ sudo ./a.sh > my.log # not as expected
# it printed
25s
27s
27s
所以它实际上只记录了2秒。
Q1:如何做我想做的事?
Q2:为什么打印到终端(或 pts?)比打印到文件更快。 (我想这就是原因。)
答案1
当它的标准输出是 tty 时,tcpdump 打开“立即模式”(通过pcap_set_immediate_mode(3)
,在支持它的系统上)和(因为 tcpdump 使用 stdio 函数进行输出)默认情况下输出将是行缓冲的。
但是当将 tcpdump 的输出重定向到文件或管道时,您必须强制两个都如果您希望将数据包“实时”记录到文件中,则显式立即模式和行缓冲。
tcpdump --immediate-mode -l > my.log
您可能还想使用该-n
选项,如果没有该选项,tcpdump
则会尝试通过 DNS 反向查找地址,这可能会花费大量时间。
tcpdump --immediate-mode -nl > my.log
当不tcpdump
交互使用时,最好使用 转储原始数据包-w
并在使用 读取转储文件时解析它们-r
。在这种情况下,如果您希望转储输出“实时”,-U
则应使用。-l
tcpdump --immediate-mode -Uw /path/to/dump
...
tail -c+0 -f /path/to/dump | tcpdump -r-