我今天做了一件愚蠢的事:
read x <( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )
它挂了,再也没有回来。我不得不打破它。
你们中的有些人现在正对我开怀大笑。 :)
我只花了一分钟的时间就知道为什么这行不通,但是我想把它作为一个问题发布(我也将在下面简短回答,但也可以自由发表),以防它绊倒了某人。
答案 0 :(得分:2)
如果将read x
替换为cat
,要花多长时间?
问题是您执行了以下命令:
read x /dev/fd/63
(通过运行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
正则表达式以获取任何输出):< / p>
$ 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手册,其中指出:
进程替换允许使用文件名引用进程的输入或输出。
结果是一个文件名(至少在Mac上,它以/dev/fd/xx
的形式表示xx
的某些数值)可用于引用过程中命令的输出替代。
答案 1 :(得分:-1)
进程替换将标准输出重定向到读取。没有任何东西进入grep
的管道中。
因此,grep
正在耐心地等待并阻塞,并且命令链从未完成。
我是这样做的:
read x pid x <<< "$( ps -fu $LOGNAME | grep ' /usr/bin/ps$' )"
那很好。整个过程运行,创建字符串输出,然后然后将结果传递到read
。
必须注意您的数据流。 :)