【问题标题】:bash variable capture stderr and stdout separately or get exit value [duplicate]bash变量分别捕获stderr和stdout或获取退出值[重复]
【发布时间】:2011-04-07 15:38:03
【问题描述】:

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

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

output=$(mycommand 2>&1)

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

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

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

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

谢谢。

【问题讨论】:

标签: bash variables stdout capture stderr


【解决方案1】:

您使用的是什么版本的bash?对于我的版本4.1.5,输出的捕获对返回码的影响

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

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

【讨论】:

  • 我忘了提到我将命令的输出通过管道传输到另一个。虽然我可以在病房后在一个单独的命令中做到这一点。谢谢。
  • 小心!有local x=$(false 2>&1) ; echo $?set x=$(false 2>&1) ; echo $?(注意local/set 在开头)输出0 而不是1,因为最后一个命令运行是local/set
【解决方案2】:

这个问题似乎只在输出被捕获到函数内的 local 变量时才出现:

$ 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

【讨论】:

  • 非常有趣!这发生在 bash 和 dash (posix) shell 中。
  • 其实 $?为局部变量声明设置,如果您只是单独声明它,然后将它分配在单独的行上,它将按照您的意愿工作。换句话说,用 x= 在你的行上方添加 local x
猜你喜欢
  • 2014-08-05
  • 2021-12-04
  • 1970-01-01
  • 2012-06-17
  • 2012-06-20
  • 2018-03-11
  • 1970-01-01
  • 2010-12-06
相关资源
最近更新 更多