【问题标题】:Bash - getting return code, stdout and stderr form piped invocationsBash - 获取返回码、标准输出和标准错误形式的管道调用
【发布时间】:2015-09-02 07:44:49
【问题描述】:

我做了一个简单的记录器,它有方法logMETHOD。它的工作是

  1. stderrstdout 放入变量log(然后放入我的全局_LOG 变量)
  2. stderrstdout 上打印stderr 调用方法的stdout,以便我可以在控制台中看到它。
  3. 返回被调用函数的返回码。

它的调用如下所示:

logMETHOD myMethod arg1 arg2 arg3

我想出了如何将标准和错误输出同时输出到 log 变量和控制台,但我无法获得正确的返回码。

到目前为止我的代码:

function logMETHOD {
    exec 5>&1
    local log
    log="$($1 ${@:2} 2>&1 | tee /dev/fd/5)"
    local retVal=$?
    _LOG+=$log$'\n'
    return $retVal
}

不幸的是,我得到的返回码来自(可能)赋值(或者来自tee)。

额外问题: 如果没有2>&1 连接stdoutstderr 也用于控制台,是否有可能实现我的目标?

我用 'PIPESTATUS' 测试了解决方案,但代码仍然是 0。

function main {
    logMETHOD alwaysError
}

function logMETHOD {
    exec 5>&1
    local log
    local retVal
    log="$( "$@" 2>&1 | tee /dev/fd/5 )"
    retVal=${PIPESTATUS[0]}
    echo "RETVAL: $retVal"
    echo "LOG: $log"
    _LOG+=$log$'\n'
    return $retVal
}

function alwaysError {
    return 1
}

main $@

【问题讨论】:

    标签: bash pipe stdout stderr


    【解决方案1】:

    PIPESTATUS 将是一个很好的解决方案,但这里它已经保存了log=... 赋值的返回值。如果你想要"$@"... 的返回值,你必须这样写:

    log="$( "$@" 2>&1 | tee /dev/fd/5; echo ${PIPESTATUS[0]}>/tmp/retval )"
    retVal=$(</tmp/retval)
    

    将它分配给变量是行不通的,因为它的范围不会扩展到调用 shell,所以你必须求助于使用临时文件。

    至于stderr$()只能提取stdout,所以如果你想单独处理,你也必须使用临时文件。

    log="$( "$@" 2>/tmp/stderr | tee /dev/fd/5; echo ${PIPESTATUS[0]}>/tmp/retval )"
    stderr_log=$(</tmp/stderr)
    retVal=$(</tmp/retval)
    

    如果你只是想避免重定向:

    log="$( "$@" |& tee /dev/fd/5; echo ${PIPESTATUS[0]}>/tmp/retval )"
    

    来自man bash

    如果使用|&,命令的标准错误,除了它的标准输出,通过管道连接到command2的标准输入;它是 2>&1 | 的简写。标准错误到标准输出的这种隐式重定向是在命令指定的任何重定向之后执行的。

    【讨论】:

      【解决方案2】:

      最简单的修复方法是使用PIPESTATUS 检索命令的退出状态。

      # There's no need to split $1 off of $@ to run the command.
      log=$( "$@" 2>&1 | tee /dev/fd/5 )
      local retVal=${PIPESTATUS[0]}
      

      【讨论】:

      • RETVAL 仍为 0 用于调用“logMETHOD ls /bullshitdirectory”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多