进程替换被管道破坏

Process substitution broken by a pipe

我今天做了一件傻事:

read x <( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )

它挂了,再也没有回来。我不得不打破它。

你们中的一些人现在正在嘲笑我。 :)

我只花了一分钟时间就明白了为什么这不起作用,但我想 post 它作为一个问题(我也会在下面简要回答,但请随意)以防万一难倒了某人。

如果将read x替换为cat,需要多长时间才能变为运行?

问题是您执行了如下命令:

read x /dev/fd/63

(如 运行ning echo read x <(…) 所见) read 坐在那里等着你输入一些东西让它放入 x

$ read x <( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )
asc def
-bash: read: `/dev/fd/63': not a valid identifier
$

shell 正在等待您输入内容,仅此而已。你不耐烦了。

如果你想将输入重定向到 read 命令,你需要一个单独的 < 来做到这一点(我需要更改 grep 正则表达式以获得任何输出) :

$ read x < <( ps -fu $LOGNAME | grep ' /usr/bin/ps' )
$ echo $x
501 16166 16164 0 7:50AM ttys000 0:00.00 grep /usr/bin/ps
$

请注意,使用最后一个 read 命令中所示的直接重定向,只会读取进程替换的第一行输入;其余的将丢失。如果你需要在一个while循环中处理多行,你需要重定向整个循环:

while read x
do
    whatever -with "$x"
done < <(ps -fu $LOGNAME | grep ' /usr/bin/ps')

另请参阅 Process Substitution 上的 Bash 手册,其中说:

Process substitution allows a process’s input or output to be referred to using a filename.

结果是一个文件名(至少在 Mac 上,对于 xx 的某些数值,它采用 /dev/fd/xx 的形式),可用于引用输出来自进程替换中的命令。