bash变量分别捕获stderr和stdout或获取退出值

bash变量分别捕获stderr和stdout或获取退出值,bash,variables,stdout,capture,stderr,Bash,Variables,Stdout,Capture,Stderr,我需要在bash脚本中捕获命令的输出和错误,并知道该命令是否成功 目前,我正在这样捕捉这两种情况: output=$(mycommand 2>&1) 然后我需要检查mycommand的退出值。如果失败了,我需要对输出做一些处理,如果命令成功了,我不需要触摸输出 因为我正在捕获输出,所以检查$?始终为0,因为bash成功地将输出捕获到变量中 这是一个非常时间敏感的脚本,因此我们试图避免任何较慢的解决方案,如输出到文件并重新读取 如果我可以将stdout捕获到一个变量,将stderr

我需要在bash脚本中捕获命令的输出和错误,并知道该命令是否成功

目前,我正在这样捕捉这两种情况:

output=$(mycommand 2>&1)
然后我需要检查mycommand的退出值。如果失败了,我需要对输出做一些处理,如果命令成功了,我不需要触摸输出

因为我正在捕获输出,所以检查$?始终为0,因为bash成功地将输出捕获到变量中

这是一个非常时间敏感的脚本,因此我们试图避免任何较慢的解决方案,如输出到文件并重新读取

如果我可以将stdout捕获到一个变量,将stderr捕获到另一个变量,这将解决我的问题,因为我可以检查错误变量是否为空


谢谢。

您使用的是哪个版本的
bash
?对于我的版本,
4.1.5
,捕获输出对返回代码没有任何影响:

pax> false; echo $?
1
pax> echo $?
0
pax> x=$(false 2>&1) ; echo $?
1

依靠非空的标准错误来检测错误并不总是一个好主意。许多程序不输出错误,只依赖返回代码。

只有在将输出捕获到函数中的局部变量时,问题才会出现:

$ echo $BASH_VERSION
3.2.48(1)-release
$ false; echo $?
1
$ echo $?
0
$ x=$(false 2>&1) ; echo $?
1
$ function f {
> local x=$(false 2>&1) ; echo $?
> }
$ f
0
$ function g {
> x=$(false 2>&1) ; echo $?
> }
$ g
1
请注意,只有函数f(它将x捕获到一个局部变量)可以表示该行为。特别是函数g,它做同样的事情,但没有“local”关键字,可以工作

因此,不能使用局部变量,也可能在使用后“取消设置”

EDITNVRAM指出,可以事先进行本地声明,以避免出现问题:

$ function h {
>   local x
>   x=$(false 2>&1) ; echo $?
> }
$ h
1

请参阅和。我忘了提到我将命令的输出通过管道传输到另一个。虽然我可以在一个单独的命令中完成。谢谢,小心!具有
本地x=$(假2>&1);echo$?
设置x=$(false 2>&1);echo$?
(开始时注意
local/set
)输出
0
而不是
1
,因为最后一次运行的命令是
local/set
。非常有趣!这发生在bash和dash(posix)shell中?是为局部变量声明设置的,如果您只需单独声明它,然后在单独的一行上分配它,它将根据您的需要工作。换句话说,用x在你的线上方加上局部x=