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>&-
<(cmd)
或 >(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/fd
被bash
使用,如果两者都可用的话(更有效,如果您不必先创建显式文件系统条目?)。以上是关于sh 等效于从命名管道读取的 bash 命令的主要内容,如果未能解决你的问题,请参考以下文章