如果启用了errexit,如何运行可能失败的命令并获取其退出代码?

Nat*_*ook 7 bash

我的所有脚本都打开了errexit; 就是我跑set -o errexit.但是,有时我想运行类似的命令grep,但是即使命令失败也希望继续执行我的脚本.

我该怎么做呢?也就是说,如何在不杀死整个脚本的情况下将命令的退出代码转换为变量?

我可以关闭errexit,但我不愿意.

gho*_*oti 6

errexit只会导致脚本终止,如果失败的命令是"未经检验的".每man shFreeBSD上:

         Exit immediately if any untested command fails in non-interactive
         mode.  The exit status of a command is considered to be explic-
         itly tested if the command is part of the list used to control an
         if, elif, while, or until; if the command is the left hand oper-
         and of an ``&&'' or ``||'' operator; or if the command is a pipe-
         line preceded by the ! keyword.
Run Code Online (Sandbox Code Playgroud)

所以..如果你想使用这样的结构:

grep -q something /path/to/somefile
retval=$?
if [ $retval -eq 0 ]; then
  do_something  # found
else
  do_something_else  # not found
fi
Run Code Online (Sandbox Code Playgroud)

你应该使用这样的结构:

if grep -q something /path/to/somefile; then
  do_something  # found
else
  do_something_else  # not found
fi
Run Code Online (Sandbox Code Playgroud)

if关键字的存在使得grep命令经过测试,因此不受影响errexit.这种方式需要较少的打字.

当然,如果您真的需要变量中的退出值,那么没有什么能阻止您使用$?:

if grep -q something /path/to/somefile; then
  do_something  # found
else
  unnecessary=$?
  do_something $unnecessary  # not found
fi
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案。请注意以下对后一个示例进行扩展的“陷阱”:`if ! 错误的; 那么 e=$?; 回显 $e; 否则回显确定;fi` 打印 `0`,因为 `!` 运算符引入了另一个计算,而 `if false; 然后回显确定;否则 e=$?; 回声 $e; fi`按预期打印`1`。 (3认同)