假设我有一个像下面这样的脚本:

useless.sh

echo "This Is Error" 1>&2
echo "This Is Output" 

我有另一个shell脚本:

alsoUseless.sh

./useless.sh | sed 's/Output/Useless/'

我想捕捉“这是错误”,或任何其他stderr从无用的。sh,到一个变量。 我们称它为ERROR。

注意,我使用了stdout。我想继续使用stdout,所以在这种情况下,将stderr重定向到stdout没有帮助。

所以,基本上,我想做

./useless.sh 2> $ERROR | ...

但这显然行不通。

我也知道我能做到

./useless.sh 2> /tmp/Error
ERROR=`cat /tmp/Error`

但这是丑陋和不必要的。

不幸的是,如果这里没有答案,这就是我要做的。

我希望还有别的办法。

有人有更好的主意吗?


当前回答

这样捕获错误文件会更简洁:

ERROR=$(</tmp/Error)

shell可以识别这一点,并且不需要运行'cat'来获取数据。

更大的问题很难。我不认为有什么简单的方法可以做到。您必须将整个管道构建到子shell中,最终将其最终标准输出发送到一个文件,以便将错误重定向到标准输出。

ERROR=$( { ./useless.sh | sed s/Output/Useless/ > outfile; } 2>&1 )

注意,分号是必需的(在经典shell中,Bourne, Korn,这是肯定的;可能在Bash中也是如此)。'{}'对所包含的命令进行I/O重定向。如前所述,它也会从sed捕获错误。

警告:正式未经测试的代码-使用风险自负。

其他回答

alsoUseless.sh

这将允许您通过sed等命令来输出无用的.sh脚本的输出,并将stderr保存在名为error的变量中。管道的结果被发送到stdout以供显示或传输到另一个命令中。

它设置了两个额外的文件描述符来管理执行此操作所需的重定向。

#!/bin/bash

exec 3>&1 4>&2 #set up extra file descriptors

error=$( { ./useless.sh | sed 's/Output/Useless/' 2>&4 1>&3; } 2>&1 )

echo "The message is \"${error}.\""

exec 3>&- 4>&- # release the extra file descriptors

我是这样做的:

#
# $1 - name of the (global) variable where the contents of stderr will be stored
# $2 - command to be executed
#
captureStderr()
{
    local tmpFile=$(mktemp)

    $2 2> $tmpFile

    eval "$1=$(< $tmpFile)"

    rm $tmpFile
}

使用示例:

captureStderr err "./useless.sh"

echo -$err-

它确实使用了一个临时文件。但至少丑陋的东西被包裹在一个函数中。

这样捕获错误文件会更简洁:

ERROR=$(</tmp/Error)

shell可以识别这一点,并且不需要运行'cat'来获取数据。

更大的问题很难。我不认为有什么简单的方法可以做到。您必须将整个管道构建到子shell中,最终将其最终标准输出发送到一个文件,以便将错误重定向到标准输出。

ERROR=$( { ./useless.sh | sed s/Output/Useless/ > outfile; } 2>&1 )

注意,分号是必需的(在经典shell中,Bourne, Korn,这是肯定的;可能在Bash中也是如此)。'{}'对所包含的命令进行I/O重定向。如前所述,它也会从sed捕获错误。

警告:正式未经测试的代码-使用风险自负。

重定向stderr到stdout, stdout到/dev/null,然后使用反勾号或$()捕获重定向的stderr:

ERROR=$(./useless.sh 2>&1 >/dev/null)

这篇文章帮助我想出了一个类似的解决方案:

MESSAGE=`{ echo $ERROR_MESSAGE | format_logs.py --level=ERROR; } 2>&1`

然后只要MESSAGE不是空字符串,我们就把它传递给其他东西。这将让我们知道我们的format_logs.py是否因某种python异常而失败。