更新

更新

在我的脚本中,我有一个复杂的命令,可以在stdout和上生成输出stderr。我需要将两者捕获到单独的变量中:

#!/bin/sh
A=$(command)

如何“捕获”stderr到变量中B

我尝试了 和 的一些变体,2>&1read不起作用:

A=$(some_command) 2>&1 | read B
echo $B

或者

{ OUT="$(command)" 2>&1 | read B ; }
echo $B

唯一有效的方法是重定向stderr到临时文件,然后将其读回。但这似乎是一个肮脏的黑客行为。有没有办法不使用临时文件来做到这一点?

更新

澄清一下,stdoutstderr都是多行输出。

答案1

老实说,使用文件可能是最简单的方法。但是,让我们在这里做出一些假设,假设您想要stdout作为单行变量,并且不关心stderr是否为 1 行(或者也将其展平)。然后让我们使用一个简单的脚本进行测试 - 其中“2”转到stderr标准输出,其他行转到标准输出:

> cat outerr.sh
echo 1
echo 2 >&2
echo 3
> ./outerr.sh
1
2
3
> ./outerr.sh 2>/dev/null
1
3

然后你可以做类似的事情:

(echo $(./outerr.sh) # Collect and flatten the stdout output 
                     # Meanwhile stderr flows through the pipe
) 2>&1|{
        read err     # This assumes stderr is one line only
        read out
        echo "err=$err"
        echo "out=$out"
}

或者如果 stderr 可以是多行的,那么

(echo $(./outerr.sh) # Collect and flatten the stdout output 
                     # Meanwhile stderr flows through the pipe
) 2>&1|tac|{         # reverse the output so the stdout line comes first
        read out
        err=$(tac)   # reverse lines again, back to the original line order
        echo "err=$err"
        echo "out=$out"
}

带输出

err=2
out=1 3

如果stdout需要保留行,您可以嵌入 \n 换行符,或者再次返回使用文件。

相关内容