sh 等效于从命名管道读取的 bash 命令

Posted

技术标签:

【中文标题】sh 等效于从命名管道读取的 bash 命令【英文标题】:sh equivalent of this bash command that reads from a named pipe 【发布时间】:2021-12-16 16:27:45 【问题描述】:

我试图弄清楚以下 bash 命令的等效版本在 sh 中是什么,首先,假设我有一个名为 myfifo 的命名管道并运行:

cat <(echo hello) myfifo

我明白了

hello

然后它等待将某些内容写入 myfifo,如果我在另一个终端上运行:

echo world > myfifo

终于明白了:

hello
world

然后命令终止,我回到 shell 准备编写新命令。这是您对该命令的期望,我想在 sh.xml 中复制这种确切的行为。现在由于 sh 没有进程替换,一个替代命令将是:

echo hello | cat - myfifo

如果我在 bash 中运行它,我再次得到与第一个命令相同的行为但是如果我在 sh 中运行它,命令永远不会结束,我的意思是我确实得到了你好,然后它等待打印任何内容写入它确实执行的 myfifo 但一旦执行它就不会终止,那么我唯一能做的就是 Ctrl-C 退出它或将管道内容保留到它继续打印的 myfifo 中。这似乎是 sh 特有的,因为在 bash 中,您会得到与

相同的行为
cat <(echo hello) myfifo

有谁知道我能做什么,所以它在 sh 中也一样???顺便说一句,我在 mac 上运行它,还没有在 linux 上尝试过,但我需要它在 mac 上运行。

【问题讨论】:

你的第二个版本在sh 对我来说很好用。 你确定没有其他进程写信给myfifo吗?这将阻止 cat 从命名管道读取 EOF。 不,你是在mac还是linux上运行的? 我在 MacOS Big Sur 上运行它 【参考方案1】:

命名管道的可用性取决于操作系统,而不是外壳。

您可以像这样使用它们,无论是在bash 还是sh

mkfifo myfifo
echo foo > myfifo
cat myfifo

或者使用文件描述符:

mkfifo myfifo

exec 3<> myfifo
echo foo >&3
cat <&3

# close fd
exec 3>&-

&lt;(cmd)&gt;(cmd) 语法是进程替换,略有不同。它用于将文件参数替换为命令的输入或输出。它在 bash 和其他 shell 中实现,但不是 POSIX sh

进程替换示例:

grep pattern <(echo foo)

或者

curl -o >(grep pattern) https://example.com/foo.txt

来自man bash

支持命名管道 (FIFO) 或命名打开文件的 /dev/fd 方法的系统支持进程替换。

【讨论】:

顺便提一下,mkfifo 是 POSIX 规范要求的,而 /dev/fd 不是。我认为 /dev/fdbash 使用,如果两者都可用的话(更有效,如果您不必先创建显式文件系统条目?)。

以上是关于sh 等效于从命名管道读取的 bash 命令的主要内容,如果未能解决你的问题,请参考以下文章

在 bash 中打开命名管道,而不读取或写入它

在 Ruby exec 语句中使用命名管道

OpenCV Python,从命名管道中读取视频

为啥 bash 在写入命名管道时关闭?

处理命名管道时,fish shell 和 bash 有啥区别?

/bin/sh:如何从 &3 重定向到命名管道?