【问题标题】:Process substitution capture stderr进程替换捕获stderr
【发布时间】:2013-03-01 19:36:21
【问题描述】:

对于这个问题,我将使用grep,因为它的使用文本打印到标准错误:

$ grep
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.

您可以通过进程替换轻松捕获标准输出:

$ read b < <(echo hello world)

但是 stderr 跳过进程替换并打印到控制台:

$ read b < <(grep)
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.

我想使用进程替换来捕获标准错误。我现在正在使用这个:

$ grep 2> log.txt

$ read b < log.txt

但我希望避免使用临时文件。

【问题讨论】:

    标签: bash stderr process-substitution


    【解决方案1】:

    将命令的标准错误重定向到标准输出:

    $ read "b" < <(grep 2>&1)
    $ echo "$b"
    Usage: grep [OPTION]... PATTERN [FILE]...
    

    虽然将命令的输出保存到 Bash 中的变量的传统方法是使用$()

    $ b=$(grep 2>&1)
    $ echo "$b"
    Usage: grep [OPTION]... PATTERN [FILE]...
    Try `grep --help' for more information.
    

    【讨论】:

    • 也许他想删除之前进入标准输出的内容,只捕获标准错误?我愿意。
    • read "b" &lt; &lt;(grep 2&gt;&amp;1) 只读取 $b 的第一行,b=$(grep 2&gt;&amp;1) 读取整个输出
    【解决方案2】:
    $ grep 2> >(sed 's/e/E/g';)
    

    您可以捕获 grep 的标准输出并将其通过管道传送到 sed 但是,我不知道为什么(以及如何避免)它需要额外的 INTRO 来返回控制并显示提示。

    编辑:您可以像这样修复这种不匹配:

    $ grep 2> >(sed 's/e/E/g';); sync
    

    【讨论】:

    • 你几乎是对的。您的进程替换中有一个不必要的;。这就是为什么你需要; sync 来解决这个问题。试一试:grep 2&gt; &gt;(sed 's/e/E/g'),您将立即获得输出。
    【解决方案3】:

    对于整个子shell,更通用的解决方案是使用exec 来重定向其标准错误。

    如果不是基于grep 的OP 示例是单个命令,而是您在子shell 中有一系列命令,那么您可以像这样重定向整个子shell 的标准错误:

    b=$(cat <(
        exec 2>&1
        echo "standard output"
        echo "standard error" 1>&2
       ))    
    
    echo $b
    

    将标准输出和标准错误的输出放入变量$b

    standard output standard error
    

    echo 语句只是将某些内容输出到标准输出和标准错误的示例。

    【讨论】:

      猜你喜欢
      • 2020-06-23
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-22
      • 2022-01-18
      • 2019-10-16
      • 2013-09-02
      相关资源
      最近更新 更多