bash:从 fifo 读取完整记录

bash:从 fifo 读取完整记录

我希望通过 FIFO 从进程 B 向进程 A 发送命令。

该命令将是一个单词或一个句子,但完全包含在以“\n”结尾的行中 - 但通常可以是由另一个字符终止的多行记录。

我尝试过的代码的相关部分看起来像这样:

流程A:

$ mkfifo ff
$ read x < ff

流程B: (从另一个终端窗口)

$ echo -n "cmd"   > ff
$ echo -n " arg1" > ff
$ echo -n " arg2" > ff
 ...    
$ echo    " argN" > ff

然而,发生的情况是,即使手册页说,默认情况下,read也会返回 value ,除非使用该选项,否则会读取终止行。cmdbash\n-d delim

所以,我接下来尝试-d delim明确指定,

$ read -d "\n" x < f`

仍然是相同的结果。

是否可以echo -n关闭 FIFO 的文件“描述符”?

我在 Ubuntu 18.04 上使用 bash 4.4.x。

答案1

是的,这正是发生的事情:

$ mkfifo p
$ while :; do cat p ; done > /dev/null  & 
$ strace -etrace=open,close bash -c 'echo -n foo > p; echo bar > p' |& grep '"p"' -A1
open("p", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0
--
open("p", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0

重定向仅在设置它们的单个命令的持续时间内生效。写入端的解决方法是 a) 使用复合块对命令进行分组,或 b)exec在整个脚本持续时间内(或直到关闭)使用打开文件描述符。

A)

{ echo -n foo; echo bar; } > p

(您还可以将命令放入函数中,并在调用该函数时使用重定向。)

b)

exec 3>p
echo -n foo >&3
echo bar    >&3
exec 3>&-         # to explicitly close it

如果你想在阅读端修复它,你需要循环read并连接你得到的字符串。由于您明确想要部分非行,并跳过文件结束条件,因此您不能使用 的退出代码来read执行任何有用的操作。

相关内容