我正在测试一些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),我会得到相同的(没有)。尝试使用stdbuf -oL为最后一个grep添加前缀无效。可以&gt;提交然后尾随它,但感觉我错过了什么。
更新:
似乎是描述符/订单/时间相关的东西。我创建了一个文件'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)-release(x86_64-redhat-linux-gnu))
答案 0 :(得分:2)
为了它的价值
$ 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到this question问题。
为了使用它,您可以选择在临时文件中捕获它或在一行中执行转换。
答案 1 :(得分:2)
awk
在输出未到达终端时进行缓冲。如果你有GNU awk,你可以使用它的fflush()函数在每次打印后刷新
gawk '{print; fflush()}' <&5 | grep foo
在这种特殊情况下,你不需要awk和grep,也可以。
awk /foo/ <&5
grep foo <&5
有关缓冲以及如何解决此问题的更多信息,请参阅BashFAQ 9。