18

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

目前,我正在像这样捕获两者:

output=$(mycommand 2>&1)

然后我需要检查 mycommand 的退出值。如果失败,我需要对输出做一些事情,如果命令成功,我不需要触摸输出。

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

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

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

谢谢。

4

2 回答 2

11

你用的是什么版本的bash?使用我的版本捕获输出对返回代码的影响为零4.1.5

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

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

于 2010-09-03T02:19:24.440 回答
10

仅当输出被捕获到函数内的局部变量时,问题似乎才显现出来:

$ 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

请注意,只有将 x 捕获到局部的函数 f 才能表达该行为。特别是,功能 g 做同样的事情,但没有 'local' 关键字,工作。

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

EDIT NVRAM 指出可以事先进行本地声明以避免该问题:

$ function h {
>   local x
>   x=$(false 2>&1) ; echo $?
> }
$ h
1
于 2011-01-21T23:21:42.640 回答