防止自动 EOF 到命名管道,并在需要时发送 EOF

iBu*_*Bug 18 shell-script text-processing fifo

我有一个程序在读取给定流中的 EOF 时自动退出(在以下情况下为 stdin )。
现在我想制作一个 shell 脚本,它创建一个命名管道并将程序的 stdin 连接到它。然后脚本使用and (以及其他在退出时自动生成 EOF 的工具)多次写入管道。我面临的问题是,当第一个完成时,它会向管道发送一个 EOF 并使程序退出。如果我使用类似的东西,那么当我打算退出程序时,我将无法发送 EOF。我正在研究一个平衡的解决方案,但无济于事。 我已经找到了如何防止 EOF 以及如何手动发送 EOF,但我无法将它们结合起来。有什么提示吗? echocatechotail -f

#!/bin/sh
mkfifo P
program < P & : # Run in background
# < P tail -n +1 -f | program
echo some stuff > P # Prevent EOF?
cat more_stuff.txt > P # Prevent EOF?
send_eof > P # How can I do this?
# fg
Run Code Online (Sandbox Code Playgroud)

phe*_*mer 16

正如其他人所指出的,一旦没有作者留下,管道的读者就会收到 EOF。因此,解决方案是确保始终有一位写入者将其打开。那位作家不必发送任何东西,只需将其打开即可。

由于您使用的是 shell 脚本,因此最简单的解决方案是告诉 shell 打开管道进行写入。然后完成后关闭它。

#!/bin/sh
mkfifo P
exec 3>P # open file descriptor 3 writing to the pipe
program < P
# < P tail -n +1 -f | program
echo some stuff > P
cat more_stuff.txt > P
exec 3>&- # close file descriptor 3
Run Code Online (Sandbox Code Playgroud)

请注意,如果省略最后一行,则在脚本退出时,文件描述符 3 将自动关闭(因此阅读器会收到 EOF)。除了方便之外,如果脚本以某种方式提前终止,这也提供了某种安全性。

  • 这个`exec 3&gt;P` 导致bash 挂起,为什么? (5认同)
  • @Wang @Patrick 事实上`exec 3&gt;P` 也挂在我的机器上的bash 中。这是因为没有从 P 读取进程。因此,解决方案是交换行`exec 3&gt;P` 和`program &lt; P &amp;`(添加&符号以便程序在后台运行)。 (4认同)
  • @macieksk `exec 3&lt;&gt;P` 怎么样?它既可以作为作家,也可以作为读者。如果需要在前台运行“程序”,则很有用。 (2认同)