读取第一行时断了水管

时间:2018-09-01 21:02:42

标签: bash shell sh fish

问题

接收第一行时需要停止管道中的先前命令。即在关闭fifo进行输入时停止命令。
我相信这里有一些商店。

历史

需要向/从简单的TCP服务器发送请求并获得响应。

echo $REQUEST | nc localhost 3333  -q3

这很好,但是总是在3秒后退出;没有-q3的用户将永远不会收到响应。
我找到了一个很好的解决方案,如何用awk关闭管道:

echo $REQUEST | nc localhost 3333  -q3 | awk '{print;exit}'

它在FISH中可以很好地工作,但在BASH和SH中仍然会阻塞3秒钟。 我在Ubuntu 16和MacOS X上测试了fish,sh和bash

沙盒

例如

sh -c  'echo line1; sleep 3; echo NEVER;'  | awk '{print;exit}'

我希望立即退出,但它会睡觉。

停止流水线的另一种方法是grep '' -m1 ,它在awk的FISH中效果很好,而在BASH和SH中则不起作用。

解决方法

mkfifo tempfi
( echo asdf; sleep 9; echo xxa; ) > tempfi &
awk '{print;exit}' <tempfi 
kill $!

看起来很丑

1 个答案:

答案 0 :(得分:2)

写入关闭的管道的程序会在随后的写入收到EPIPE错误时找出那些关闭的管道。如果程序在进行后续写操作之前处于睡眠状态(在阅读器消耗完所有需要的时间之后),则它尚未收到EPIPE,因此尚不知道退出。

您可以避免用流程替换来担心这一点:

read -r line < <(echo asdf; sleep 9; echo xxa)
printf '%s\n' "$line"

...从运行echo asdf; sleep 9; echo xxaread之前,不等待运行printf的子shell退出。