如何防止终止命令将 EOF 发送到命名管道?

如何防止终止命令将 EOF 发送到命名管道?

我面临的问题正是这个:http://www.linuxmisc.com/4-linux/d7863c256bccbfb6.htm

我希望能够运行一个接受 stdin 的程序,并在需要时向其中写入数据。我可以使用 fifo 命名管道来实现这一点。例如:

txtplay < named_pipe.fifo

echo "Hello World" > named_pipe.fifo

但是,这样做的缺点是第一个命令在第二个命令完成后退出。我想要的是:

txtplay

实际上,这样我就可以随时插入数据,而不必担心它看到文件结尾。不幸的是,我不能简单地这样做,因为我希望将数据发送给它,在程序看到它之前先通过过滤器进行处理。

为什么我不每次想要发送数据时都加载程序呢?太慢了。

基本上,我想要的是一种将给定命令的输出重定向到 fifo 命名管道的方法,而无需文件结尾。顺便问一下,这个 EOF 业务是如何工作的?是否有特殊的“EOF”命令,或者是在没有收到更多数据时,还是在输出数据的原始程序退出时?

有没有什么解决办法?

答案1

在子 shell 中(或在 bash 中,在括号内)运行所有命令,并将子 shell 重定向到命名管道。

( 
     # some stuff
     echo "foo"
     # some other stuff
     echo "bar"
     # end of my commands
) > /home/foo/bar/named_pipe

回答 EOF 问题,文件句柄关闭时写入 EOF。如果您从程序重定向,则当该程序(在本例中为 echo)终止时会获得 EOF。通过将多个命令封装在括号中,当到达右括号时,您只会获得一个 EOF。

答案2

如果您保持管道句柄打开,那么它将不会被每个 echo 命令关闭。

#!/usr/bin/env bash
fifo_with_exec() {
    echo "fifo_with_exec"

    readonly TMP_PIPE=$(mktemp -u)
    mkfifo -m 600 ${TMP_PIPE}
    echo "pipe created:  ${TMP_PIPE}"

    # Here is the important bit
    exec 9<> ${TMP_PIPE}

    zenity --progress --no-cancel < ${TMP_PIPE} &
    zenity_pid=$!
    echo "zenity_pid: ${zenity_pid}"

    echo "0" > ${TMP_PIPE}
    echo "#Run command A" > ${TMP_PIPE}
    echo "output of command A"
    sleep 2
    echo "40"  > ${TMP_PIPE}

    echo "#Run command B" > ${TMP_PIPE}
    echo "output of command B"
    sleep 2
    echo "80" > ${TMP_PIPE}

    echo "#Run command C" > ${TMP_PIPE}
    echo "output of command C"
    sleep 0.5
    echo "100" > ${TMP_PIPE}
}
fifo_with_exec

如果删除该 exec 语句,您会注意到该函数在第二次回显上挂起,因为 Zenity 在看到第一次回显的 EOF 时停止。

相关内容