当'set -e'处于活动状态时,Bash获取命令的退出状态?

时间:2013-09-04 19:16:47

标签: bash

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

没有set +e; some-command; res=$?; set -e舞蹈,我怎么能这样做?

4 个答案:

答案 0 :(得分:54)

来自bash手册:

  

如果失败的命令是&&amp ;;中执行的任何命令的一部分,则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

这是规范的做法。

答案 1 :(得分:12)

作为替代

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

答案 2 :(得分:6)

也许尝试在子shell中运行有问题的命令,比如这个?

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

答案 3 :(得分:-3)

使用包装函数执行命令:

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

__e yourcommand arg1 arg2

使用$__r代替$?

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

在管道中调用命令的另一种方法,只需要引用管道。这样做是安全的。

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
...