当'set -e'激活时,Bash会得到命令的退出状态吗?

我通常在我的Bash脚本中设置了-e ,但偶尔我想运行一个命令并获取返回值。

不用做set +e; some-command; res=$?; set -e set +e; some-command; res=$?; set -e set +e; some-command; res=$?; set -e跳舞,我该怎么做?

bash手册:

如果失败的命令是在&&或||中执行的任何命令的一部分,shell不会退出 列表[…]。

所以,只要:

 #!/bin/bash set -eu foo() { # exit code will be 0, 1, or 2 return $(( RANDOM % 3 )) } ret=0 foo || ret=$? echo "foo() exited with: $ret" 

示例运行:

 $ ./foo.sh foo() exited with: 1 $ ./foo.sh foo() exited with: 0 $ ./foo.sh foo() exited with: 2 

这是做这个规范的方法。

作为备选

 ans=0 some-command || ans=$? 

也许尝试在子shell中运行有问题的命令,像这样?

 res=$(some-command > /dev/null; echo $?) 

使用包装函数来执行你的命令:

 function __e { set +e "$@" __r=$? set -e } __e yourcommand arg1 arg2 

并使用$__r而不是$?

 if [[ __r -eq 0 ]]; then echo "success" else echo "failed" fi 

另一种在pipe道中调用命令的方法,只是必须引用pipe道。 这是一个安全的评估。

 function __p { set +e local __A=() __I for (( __I = 1; __I <= $#; ++__I )); do if [[ "${!__I}" == '|' ]]; then __A+=('|') else __A+=("\"\$$__I\"") fi done eval "${__A[@]}" __r=$? set -e } 

例:

 __p echo abc '|' grep abc 

而我更喜欢这个语法:

 __p echo abc :: grep abc 

我可以做什么

 ... if [[ ${!__I} == '::' ]]; then ...