用 cat 进行简单的进程替换似乎挂起:
cat >( echo hello; )
永远不会结束。也试过:
cat >( echo hello; exit; )
从子进程手动关闭标准输出文件描述也不起作用:
cat >( echo hello; 1>&- )
cat >( echo hello; 1>&- exit; )
我尝试过使用 GNU bash,版本 4.4.23(1)-release,GNU bash,版本 4.1.2(2)-release 和 zsh 5.5.1 (x86_64-debian-linux-gnu)
有人可以解释为什么会这样吗?我真的很喜欢过程替换......
谢谢
编辑:如果 cat 要从 echo 中读取,则进程替换中的正确重定向是:
cat <( echo hello; )
你的代码
cat >( echo hola; )
永远不会退出,因为,hola
Ctrl+D
它继续搜索要写入的文件时。选项 1:将上下文写入回显的文件
因此,无论我们在下面给出什么上下文,都将保存到名为
hola
.注意:我们可以通过以下方式退出 cat 块
Ctrl+D
选项 2:捕捉回显的上下文。
我不知道您要完成什么,但是:
>(...)
使正在运行的任何内容的标准输入都可用于编写cat
需要一个可以读取的文件无法保证 (1) 提供的任何内容都可以读取。在 macOS 上,我得到一个错误:
在 Linux 上,对我来说,它是另一端的管道,没有任何东西在写:
和:
另一端的任何东西都关闭了标准输入并退出并不重要——它只打开管道进行读取,而不是写入,并且没有任何内容写入管道。所以
cat
会留在那里,等待阅读完成。(两者strace
和cat
这里都有一个用于写入该管道的打开文件句柄,但那是因为 bash 将其打开以进行写入并使其可供他们使用。两者都不会写入它。)流程替代本身就是一个主题。要意识到的重要部分是它更像是一个 FIFO,而不是标准输入或标准输出。您可以通过 echo 看到这一点:
给你:/dev/fd/63 你好
外部回声为您提供实际给出的论点,即
/dev/fd/63
. 所以,你的实际上是
cat /dev/fd/43
并且输出被发送到echo hello
. (43 只是一个例子;这个数字是随机的,但通常是 63)您还可以看到两者之间的区别:
这给了
hop
和这给出了
hop /dev/fd/63
.另外,举个例子:
这给出了输入
klop
是进程替换的标准
klopklap
输出,tee
并且是 进程替换hopklopklap
的标准输出。sed
那么为什么会
cat >(echo hello)
挂起呢?因为,如前所述, cat 得到一个参数/dev/fd/32
,并且从那个“文件”中它永远不会得到一个 EOF。cat
不会挂起,它正在等待您的输入。cat
读取标准输入并写入标准输出。您不重定向标准输入,因此标准输入是您的终端。当您键入 时Ctrl+D
,您表示文件结束,您的cat
遗嘱将终止。