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

mho*_*ost 17 variables bash stdout capture stderr

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

目前,我正在捕捉这两个:

output=$(mycommand 2>&1)
Run Code Online (Sandbox Code Playgroud)

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

由于我正在捕获输出,检查$?因为bash成功地将输出捕获到变量中,所以总是为0.

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

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

谢谢.

pax*_*blo 10

bash你用的是什么版本的?使用我的版本捕获输出对返回代码没有任何影响4.1.5:

pax> false; echo $?
1
pax> echo $?
0
pax> x=$(false 2>&1) ; echo $?
1
Run Code Online (Sandbox Code Playgroud)

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

  • 警告!有'本地x = $(假2>&1); echo $?`或`set x = $(false 2>&1); echo $?`(注意**在开头的`local/set`**)输出`0`而不是`1`,因为最后一个命令运行是`local/set`. (4认同)

phs*_*phs 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
Run Code Online (Sandbox Code Playgroud)

请注意,只有将x捕获到本地的函数f才能表达行为.特别是,函数g执行相同的操作,但没有'local'关键字,可以工作.

因此,人们不能使用局部变量,并且可能在使用后"取消设置"它.

编辑 NVRAM指出可以事先做出本地声明以避免问题:

$ function h {
>   local x
>   x=$(false 2>&1) ; echo $?
> }
$ h
1
Run Code Online (Sandbox Code Playgroud)

  • 实际上是$?为局部变量声明设置,如果你只是单独声明它,_then_在一个单独的行上分配它,它将按你的意愿工作.换句话说,使用**x =**在您的行上方添加**local x** (3认同)