Suz*_*Soy 4 io-redirection process-substitution
进程替换<(cat)
不起作用。为什么?
head <(cat)
cat: -: Input/output error
Run Code Online (Sandbox Code Playgroud)
我可以使用额外的文件描述符,但我不明白为什么上述方法不起作用。
# Using file descriptor 3 to reroute the input
(head <(cat <&3)) 3<&0
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
在所有 3 个 shell 中,ps
进程与 的进程组位于不同的进程组中cat
,后者是终端的前台进程组。zsh
至少足以将 stdin 重定向到那里,/dev/null
如果它是一个 tty 以避免出现问题,就像许多 shell 对在后台运行的命令所做的那样。
如果 stdin 不是终端,您的命令可以正常工作,但在这里,由于cat
不在终端的前台进程组中,它从终端读取意味着它将收到一个SIGTTIN
信号,导致它被挂起。而这在这里处理得并不优雅。在您的情况下,它似乎SIGTTIN
被忽略或阻止,因为您会收到 EIO 错误(当您不在其前台进程组和 ignore/block 中尝试从控制终端读取时会收到该错误SIGTTIN
)。
在
(head <(cat <&3)) 3<&0
Run Code Online (Sandbox Code Playgroud)
但是,我们在前台启动了一个子 shell,并且那里的所有进程最终都在同一个进程组中,因此允许从终端读取。有了显式重定向zsh
,我们就绕过了zsh
从 的重定向/dev/null
。与其他贝壳,
(head <(cat))
Run Code Online (Sandbox Code Playgroud)
也会工作。
归档时间: |
|
查看次数: |
977 次 |
最近记录: |