如何将带有grep表达式的tcpdump输出到stdout/file?

如何将带有grep表达式的tcpdump输出到stdout/file?,grep,tcpdump,sysadmin,Grep,Tcpdump,Sysadmin,我正在尝试将以下tcpdump grep表达式输出到文件: tcpdump-vvs 1024-l-A tcp端口80 | grep-E'X-Forwarded-For:'-行缓冲| awk'{print$2} 我知道它与line buffered选项有关,该选项将输出发送到stdin。然而,如果我不使用-line缓冲,我就不会从tcpdump获得任何输出 在这种情况下,如何使用grep将我的输出直接发送到stdout/file 我试图将以下tcpdump grep表达式输出到一个文件 然后将管道

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

tcpdump-vvs 1024-l-A tcp端口80 | grep-E'X-Forwarded-For:'-行缓冲| awk'{print$2}

我知道它与line buffered选项有关,该选项将输出发送到stdin。然而,如果我不使用-line缓冲,我就不会从tcpdump获得任何输出

在这种情况下,如何使用grep将我的输出直接发送到stdout/file

我试图将以下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不符:

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

-行缓冲会改变这种行为,因此每一行在生成时都会写入管道,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在grep看到并匹配它时立即看到包含X-Forwarded-For:的每一行

然而,如果我不使用-line缓冲,我就不会从tcpdump获得任何输出

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

在这种情况下,如何使用grep将我的输出直接发送到stdout/file

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

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

我试图将以下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不符:

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

-行缓冲会改变这种行为,因此每一行在生成时都会写入管道,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在grep看到并匹配它时立即看到包含X-Forwarded-For:的每一行

然而,如果我不使用-line缓冲,我就不会从tcpdump获得任何输出

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

在这种情况下,如何使用grep将我的输出直接发送到stdout/file

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

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

感谢您澄清关于行缓冲的内容。然而,我的命令根本不向文件输出任何内容,所以肯定有什么地方出错了。如果不尝试输出到文件,我可以看到正在打印的行,但无论显示多少数据,它们都不会写入文件。如果我remove-line bufferedmy命令根本不向文件输出任何内容,也会发生同样的情况。您是否将awk的标准输出重定向到该文件?也就是说,您的命令是否以>{filename}结尾,其中{filename}是要将解析的数据包打印到的文件的名称?是的,我在我的帖子中写了这个命令:tcpdump-vvs 1024-l-A tcp端口80 | grep-e'X-Forwarded-For:'-行缓冲| awk'{print$2}'>文件不幸的是,在这种情况下awk也会缓冲其输出。尝试tcpdump-vvs 1024-l-A tcp端口80 | grep-E'X-Forwarded-For:'行缓冲| awk'{print$2};fflushstdout'>文件,以使其刷新每一行的输出。+1用于注释,指出tcpdump命令包含-l,该命令与grep缓冲的-line的作用相同。这正是让我的grep从tcpdump开始工作所需要的。好吧,至少要让grep更快地看到输出!感谢您澄清关于行缓冲的问题。然而,我的命令根本不向文件输出任何内容,所以肯定有什么地方出错了。如果不尝试输出到文件,我可以看到正在打印的行,但无论显示多少数据,它们都不会写入文件。如果我remove-line bufferedmy命令根本不向文件输出任何内容,也会发生同样的情况。您是否将awk的标准输出重定向到该文件?也就是说,您的命令是否以>{filename}结尾,其中{filename}是要将解析的数据包打印到的文件的名称?是的,我在我的帖子中写了这个命令:tcpdump-vvs 1024-l-A tcp端口80 | grep-e'X-Forwarded-For:'-行缓冲| awk'{print$2}'>文件不幸的是,在这种情况下awk也会缓冲其输出。尝试tcpdump-vvs 1024-l-A tcp端口80 | grep-E'X-Forwarded-For:'行缓冲| awk'{print$2};fflushstdout'>文件,以使其刷新每一行的输出。+1用于注释,指出tcpdump命令包含-l,该命令与grep缓冲的-line的作用相同。这正是让我的grep从tcpdump开始工作所需要的。好吧,至少要让grep更快地看到输出!