如何使用grep表达式将tcpdump输出到stdout / file?

时间:2015-10-11 12:50:19

标签: grep tcpdump sysadmin

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

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

据我所知,它与line-buffered选项有关,它将输出发送到stdin。但是,如果我不使用--line-buffered,我的tcpdump根本没有任何输出。

如何使用grep以便在这种情况下将输出直接发送到stdout / file?

1 个答案:

答案 0 :(得分:3)

  

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

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

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

据我所知,它与line-buffered选项有关,它将输出发送到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.

因此它不会改变输出的位置,只是当数据实际写入输出描述符时它才会改变,如果它不是终端的话。在这种情况下,它不是一个终端 - 它是一个管道 - 所以,默认情况下,它是块缓冲的,所以如果grep写入4行输出,那么小于a完整的缓冲区块(在这种情况下,缓冲区块,在大多数现代UN * Xes和Windows上通常是4K字节,因此这4条线路很可能不会填充缓冲区),这些线路将< em> not 会立即由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看到包含&#34; X-的每一行。转发-对于:&#34;一旦grep看到它并匹配它。

  

但是,如果我不使用--line-buffered,我根本不会从tcpdump获得任何输出。

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

  

如何使用grep以便在这种情况下将输出直接发送到stdout / file?

grep将其(标准)输出发送到awk,这可能是你想要的;你从grep的输出中提取第二个字段并仅打印出来。

因此,您不希望 grep (标准)输出直接发送到终端或文件,您希望它将其输出发送到awk并让 awk 在那里发送其(标准)输出。如果您希望在终端上打印输出,那么您的命令正在做正确的事情;如果您希望将其发送到文件,请将awk的标准输出重定向到该文件。