Bash get exit status of command when 'set -e' is active?

前端 未结 4 1435
暗喜
暗喜 2020-12-25 09:55

I generally have -e set in my Bash scripts, but occasionally I would like to run a command and get the return value.

Without doing the set +e; som

相关标签:
4条回答
  • 2020-12-25 10:02

    From the bash manual:

    The shell does not exit if the command that fails is [...] part of any command executed in a && or || list [...].

    So, just do:

    #!/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"
    

    Example runs:

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

    This is the canonical way of doing it.

    0 讨论(0)
  • 2020-12-25 10:09

    Maybe try running the commands in question in a subshell, like this?

    res=$(some-command > /dev/null; echo $?)
    
    0 讨论(0)
  • 2020-12-25 10:23

    as an alternative

    ans=0
    some-command || ans=$?
    
    0 讨论(0)
  • 2020-12-25 10:24

    Use a wrapper function to execute your commands:

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

    And use $__r instead of $?:

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

    Another method to call commands in a pipe, only that you have to quote the pipe. This does a safe eval.

    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
    }
    

    Example:

    __p echo abc '|' grep abc
    

    And I actually prefer this syntax:

    __p echo abc :: grep abc
    

    Which I could do with

    ...
            if [[ ${!__I} == '::' ]]; then
    ...
    
    0 讨论(0)
提交回复
热议问题