进程替换<(cat)
不起作用。为什么?
head <(cat)
cat: -: Input/output error
我可以使用额外的文件描述符,但我不明白为什么上面的方法不起作用。
# Using file descriptor 3 to reroute the input
(head <(cat <&3)) 3<&0
答案1
在 中bash
,如果您这样做:
$ cat <(ps -j)
PID PGID SID TTY TIME CMD
3887 16480 16480 pts/29 00:00:00 bash
3888 3888 16480 pts/29 00:00:00 cat
3889 16480 16480 pts/29 00:00:00 ps
16480 16480 16480 pts/29 00:00:00 bash
在zsh
:
$ cat <(ps -j)
PID PGID SID TTY TIME CMD
3935 3935 16480 pts/29 00:00:00 ps
3936 3936 16480 pts/29 00:00:00 cat
16480 16480 16480 pts/29 00:00:00 zsh
在ksh93
:
$ cat <(ps -j)
PID PGID SID TTY TIME CMD
3946 16480 16480 pts/29 00:00:00 ps
3947 3947 16480 pts/29 00:00:00 cat
16480 16480 16480 pts/29 00:00:00 ksh
在所有 3 个 shell 中,ps
进程都位于与cat
终端的前台进程组不同的进程组中。zsh
至少可以将 stdin 重定向到/dev/null
tty 以避免出现问题,就像许多 shell 对在后台运行的命令所做的那样。
如果 stdin 不是终端,则您的命令可以正常工作,但在这里,由于cat
不在终端的前台进程组中,因此它从终端读取意味着它将收到一个SIGTTIN
信号,这将导致它被挂起。这里处理得并不优雅。在您的情况下,它似乎SIGTTIN
被忽略或阻止,导致您收到 EIO 错误(当您不在其前台进程组并忽略/阻止时尝试从控制终端读取时,您会收到该错误SIGTTIN
)。
在
(head <(cat <&3)) 3<&0
但是,我们在前台启动一个子 shell,其中的所有进程最终都位于同一进程组中,因此允许从终端读取。通过其中的显式重定向,zsh
我们绕过了zsh
来自 的重定向/dev/null
。与其他贝壳一起,
(head <(cat))
也会起作用。