grep - 如何将带有 grep 表达式的 tcpdump 输出到标准输出/文件?

标签 grep tcpdump sysadmin

我正在尝试将以下 tcpdump grep 表达式输出到文件中:

tcpdump -vvvs 1024 -l -A TCP 端口 80 | grep -E 'X-Forwarded-For:' --line-buffered | awk '{打印 $2}

我知道它与行缓冲选项有关,它将输出发送到标准输入。但是,如果我不使用 --line-buffered,我的 tcpdump 根本得不到任何输出。

在这种情况下,如何使用 grep 将我的输出直接发送到标准输出/文件?

最佳答案

I am trying to output the following tcpdump grep expression to a file

然后将管道中最后一个命令的输出重定向到文件中:

tcpdump -vvvs 1024 -l -A tcp port 80 | grep -E 'X-Forwarded-For:' --line-buffered | awk '{print $2}' >file

I understand it is related to the line-buffered option, that sends the output to stdin.

不,这不是 --line-buffered 做的:

$ man grep

    ...

     --line-buffered
             Force output to be line buffered.  By default, output is line
             buffered when standard output is a terminal and block buffered
             otherwise.

所以它不会改变输出的位置,如果它不是终端,它只会在数据实际写入输出描述符时发生变化。在这种情况下它不是终端 - 它是管道 - 所以,默认情况下,它是 block 缓冲的,所以如果 grep 写入 4 行输出,并且它小于一个完整的缓冲 block (缓冲 block ,在这种情况下,通常是 4K 字节在大多数现代 UN*Xes 和 Windows 上,所以这 4 行很可能不会填满缓冲区),这些行不会立即由 grep 写入管道,因此它们不会立即出现。

--line-buffered 更改了该行为,因此每一行在生成时都写入管道,并且 awk 会更快地看到它。

您正在将 -l 与 tcpdump 一起使用,它具有相同的效果,至少在 UN*X 上是这样:

$ 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.

因此,正如您编写的那样,管道将导致 grep 在 tcpdump 打印时立即看到 tcpdump 打印的每一行,并导致 awk 看到包含“X-Forwarded-For:”的每一行一旦 grep 看到并匹配它。

However, if I don't use --line-buffered I don't get any output at all from my tcpdump.

最终您会看到它,只要 grep 产生缓冲区的输出值;但是,这可能需要很长时间。 --line-buffered 导致 grep 在生成每一行时写出它,因此它会在 grep 生成它时立即显示,而不是缓冲区已满。

How can I use grep so that it will send my output directly to stdout / file in this case ?

grep 正在将其(标准)输出发送到 awk,这大概是您想要的;您正在从 grep 的输出中提取第二个字段并仅打印它。

所以您不希望 grep它的(标准)输出直接发送到终端或文件,您希望它将其输出发送到 awk 并且让 awk 将其(标准)输出发送到那里。如果您希望在您的终端上打印输出,那么您的命令是正确的;如果你想把它发送到一个文件,将 awk 的标准输出重定向到那个文件。

关于grep - 如何将带有 grep 表达式的 tcpdump 输出到标准输出/文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33065155/

相关文章:

network-programming - wireshark 如何将一些数据包标记为 "tcp segment of a reassembled pdu"

linux - VMWare Server Under Linux Secondary NIC 连接

bash - 我可以 grep 多个模式但有一些是相反的吗?

regex - 为什么 grep 不能在这种模式下使用冒号?

linux - 删除空行旁边一行的 Shell 脚本

bash - 在后台 linux 中运行 tcpdump

linux - 如何使用 cli 读取 pcap 文件并保存数据?

php - 无法通过 Laravel SQLSTATE [08006] [7] FATAL 连接到 PgSQL

linux - 在 Slurm 抢占挂起事件上运行脚本

bash - shell命令查找进程ID并附加到它?