监听 netcat 工作但不能 grep'able(或其他几个实用程序)
listening on netcat works but not grep'able (or several other utilities)
我正在测试一些 netcat udp shell 工具,并尝试获取输出并通过标准管道发送。在此示例中,我有一个 netcat 客户端,它发送 'foo' 然后 'bar' 然后 'foo' 每次尝试从侦听器读取时带有换行符:
[root@localhost ~ 05:40:20 ]# exec 5< <(nc -d -w 0 -6 -l -k -u 9801)
[root@localhost ~ 05:40:25 ]# awk '{print}' <&5
foo
bar
foo
^C
[root@localhost ~ 05:40:48 ]# awk '{print}' <&5 | grep foo
^C
[root@localhost ~ 05:41:12 ]# awk '{print}' <&5 | grep --line-buffered foo
^C
[root@localhost ~ 05:41:37 ]#
[root@localhost ~ 05:44:38 ]# grep foo <&5
foo
foo
^C
[root@localhost ~ 05:44:57 ]#
我已经检查了 --line-buffered... 我也从 'od -bc' 得到了相同的行为,即什么也没有。 Grep 在 fd 上工作......但是如果我将该 grep 传递给任何东西(比如 od -bc,cut),我得到相同的(没有)。尝试在最后一个 grep 前加上 stdbuf -oL,但无济于事。可以 > to file 然后 tail -f 它,但感觉好像遗漏了什么。
更新:
似乎与 descriptor/order/timing 相关。我创建了一个文件 'tailSource' 并使用了它,当我 运行 echo -e "foo\nfoo\nbar\nfoo" >> tailSource
时产生了同样的问题(没有输出)
[root@localhost shm 07:16:18 ]# exec 5< <(tail -n 0 -f tailSource)
[root@localhost shm 07:16:32 ]# awk '{print}' <&5 | grep foo
... 当我 运行 没有 '| grep foo',我得到了我期望的输出。
(GNU bash, 版本 4.1.2(1)-发布 (x86_64-redhat-linux-gnu))
物有所值
$ exec 5< <(echo -e "foo\nbar\nfoo")
$ awk '{print}' <&5 | grep foo
打印
foo
foo
其中
$ exec 5< <(echo -e "foo\nbar\nfoo")
$ awk '{print}' <&5
foo
bar
foo
$ awk '{print}' <&5
$
第二次调用没有任何输出。
我认为这是因为文件描述符已结束,您需要倒回它,另请参阅 this answer to this question 问题。
为了使用它,您可以选择将其捕获到临时文件中或在一行中执行转换。
awk
在其输出不进入终端时正在缓冲。如果你有 GNU awk,你可以使用它的 fflush() 函数在每次 print
后刷新
gawk '{print; fflush()}' <&5 | grep foo
虽然在这种特殊情况下,您不需要 awk 和 grep,两者都可以。
awk /foo/ <&5
grep foo <&5
有关缓冲及其解决方法的更多信息,请参阅 BashFAQ 9。
我正在测试一些 netcat udp shell 工具,并尝试获取输出并通过标准管道发送。在此示例中,我有一个 netcat 客户端,它发送 'foo' 然后 'bar' 然后 'foo' 每次尝试从侦听器读取时带有换行符:
[root@localhost ~ 05:40:20 ]# exec 5< <(nc -d -w 0 -6 -l -k -u 9801)
[root@localhost ~ 05:40:25 ]# awk '{print}' <&5
foo
bar
foo
^C
[root@localhost ~ 05:40:48 ]# awk '{print}' <&5 | grep foo
^C
[root@localhost ~ 05:41:12 ]# awk '{print}' <&5 | grep --line-buffered foo
^C
[root@localhost ~ 05:41:37 ]#
[root@localhost ~ 05:44:38 ]# grep foo <&5
foo
foo
^C
[root@localhost ~ 05:44:57 ]#
我已经检查了 --line-buffered... 我也从 'od -bc' 得到了相同的行为,即什么也没有。 Grep 在 fd 上工作......但是如果我将该 grep 传递给任何东西(比如 od -bc,cut),我得到相同的(没有)。尝试在最后一个 grep 前加上 stdbuf -oL,但无济于事。可以 > to file 然后 tail -f 它,但感觉好像遗漏了什么。
更新:
似乎与 descriptor/order/timing 相关。我创建了一个文件 'tailSource' 并使用了它,当我 运行 echo -e "foo\nfoo\nbar\nfoo" >> tailSource
[root@localhost shm 07:16:18 ]# exec 5< <(tail -n 0 -f tailSource)
[root@localhost shm 07:16:32 ]# awk '{print}' <&5 | grep foo
... 当我 运行 没有 '| grep foo',我得到了我期望的输出。 (GNU bash, 版本 4.1.2(1)-发布 (x86_64-redhat-linux-gnu))
物有所值
$ exec 5< <(echo -e "foo\nbar\nfoo")
$ awk '{print}' <&5 | grep foo
打印
foo
foo
其中
$ exec 5< <(echo -e "foo\nbar\nfoo")
$ awk '{print}' <&5
foo
bar
foo
$ awk '{print}' <&5
$
第二次调用没有任何输出。
我认为这是因为文件描述符已结束,您需要倒回它,另请参阅 this answer to this question 问题。
为了使用它,您可以选择将其捕获到临时文件中或在一行中执行转换。
awk
在其输出不进入终端时正在缓冲。如果你有 GNU awk,你可以使用它的 fflush() 函数在每次 print
gawk '{print; fflush()}' <&5 | grep foo
虽然在这种特殊情况下,您不需要 awk 和 grep,两者都可以。
awk /foo/ <&5
grep foo <&5
有关缓冲及其解决方法的更多信息,请参阅 BashFAQ 9。