【问题标题】:Process substitution broken by a pipe被管道中断的进程替换
【发布时间】:2019-02-14 15:35:14
【问题描述】:

我今天做了一件傻事:

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

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

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

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

【问题讨论】:

  • “现在在笑我是对的”XD

标签: bash pipe io-redirection command-substitution


【解决方案1】:

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

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

read x /dev/fd/63

(你可以通过运行echo read x &lt;(…) 看到) read 坐在那里等你输入一些东西让它输入x

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

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

如果您想将输入重定向到read commnd,您需要一个单独的&lt; 来执行此操作(我需要更改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 手册,其中说:

进程替换允许使用文件名来引用进程的输入或输出。

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

【讨论】:

    【解决方案2】:

    进程替换正在将标准输出重定向到读取。没有任何东西进入grep 的管道。

    因此,grep 正在耐心等待和阻塞,命令链永远不会结束。

    我是这样做的:

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

    效果很好。整个过程运行,创建一个字符串输出,然后将结果传递给read

    必须注意您的数据流。 :)

    【讨论】:

    • 对不起;这是不正确的分析。我认为,请参阅我的答案以找到更好的答案。
    • 这就是我费心发帖的原因。 有人会学到一些东西,可能就是我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 2013-07-12
    • 2014-01-01
    相关资源
    最近更新 更多