Rda*_*ang 2 grep system-administration tcpdump
我正在尝试将以下 tcpdump grep 表达式输出到文件中:
tcpdump -vvvs 1024 -l -A TCP 端口 80 | grep -E 'X-Forwarded-For:' --line-buffered | grep -E 'X-Forwarded-For:' --line-buffered | awk '{打印$2}
我知道它与行缓冲选项有关,该选项将输出发送到标准输入。但是,如果我不使用 --line-buffered,我根本不会从 tcpdump 中获得任何输出。
在这种情况下,如何使用 grep 以便将我的输出直接发送到 stdout/文件?
小智 7
我正在尝试将以下 tcpdump grep 表达式输出到文件中
然后将管道中最后一个命令的输出重定向到文件:
tcpdump -vvvs 1024 -l -A tcp port 80 | grep -E 'X-Forwarded-For:' --line-buffered | awk '{print $2}' >file
Run Code Online (Sandbox Code Playgroud)
我知道它与行缓冲选项有关,该选项将输出发送到标准输入。
不,那不是--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.
Run Code Online (Sandbox Code Playgroud)
因此它不会改变输出的位置,只是在数据实际写入输出描述符(如果它不是终端)时发生变化。在这种情况下,它不是终端 - 它是一个管道 - 因此,默认情况下,它是块缓冲的,因此如果 grep 写入 4 行输出,并且这小于完整的缓冲区块(在这种情况下,缓冲区块通常为 4K 字节)在大多数现代 UN*Xes 和 Windows 上,因此这 4 行很可能不会填充缓冲区),这些行不会立即由 grep 写入管道,因此它们不会立即显示。
--line-buffered更改该行为,以便每一行在生成时都写入管道,并且 awk 可以更快地看到它。
您正在使用-ltcpdump,它具有相同的效果,至少在 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.
Run Code Online (Sandbox Code Playgroud)
因此,正如您所编写的,管道将导致 grep 在 tcpdump 打印后立即查看 tcpdump 打印的每一行,并导致 awk 立即查看包含“X-Forwarded-For:”的每一行grep 看到它并匹配它。
但是,如果我不使用 --line-buffered,我根本不会从 tcpdump 中获得任何输出。
只要 grep 产生一个缓冲区的输出,您最终就会看到它;然而,这可能需要很长时间。 --line-buffered导致 grep 在生成时写出每一行,因此 grep 生成它时就会显示它,而不是缓冲区已满。
在这种情况下,如何使用 grep 以便将我的输出直接发送到 stdout/文件?
grep 正在将其(标准)输出发送到 awk,这可能就是您想要的;您从 grep 的输出中提取第二个字段并仅打印该字段。
因此,您不希望grep将其(标准)输出直接发送到终端或文件,您希望它将其输出发送到 awk 并让awk将其(标准)输出发送到那里。如果您希望将输出打印在终端上,那么您的命令就是在做正确的事情;如果您希望将其发送到文件,请将 awk 的标准输出重定向到该文件。