How to trap ERR when using 'set -e' in Bash

前端 未结 3 1947
刺人心
刺人心 2020-12-13 03:42

I have a simple script :

#!/bin/bash
set -e
trap \"echo BOO!\" ERR 

function func(){
    ls /root/
}

func

I would like to trap ERR if my

相关标签:
3条回答
  • 2020-12-13 04:15

    You need to use set -o errtrace for the function to inherit the trap.

    0 讨论(0)
  • 2020-12-13 04:22

    chepner's answer is the best solution: If you want to combine set -e (same as: set -o errexit) with an ERR trap, also use set -o errtrace (same as: set -E).

    In short: use set -eE in lieu of just set -e:

    #!/bin/bash
    
    set -eE  # same as: `set -o errexit -o errtrace`
    trap 'echo BOO!' ERR 
    
    function func(){
      ls /root/
    }
    
    # Thanks to -E / -o errtrace, this still triggers the trap, 
    # even though the failure occurs *inside the function*.
    func 
    

    A more sophisticated example trap example that prints the message in red and also prints the exit code:
    trap 'printf "\e[31m%s: %s\e[m\n" "BOO!" $?' ERR


    man bash says about set -o errtrace / set -E:

    If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases.

    What I believe is happening:

    • Without -e: The ls command fails inside your function, and, due to being the last command in the function, the function reports ls's nonzero exit code to the caller, your top-level script scope. In that scope, the ERR trap is in effect, and it is invoked (but note that execution will continue, unless you explicitly call exit from the trap).

    • With -e (but without -E): The ls command fails inside your function, and because set -e is in effect, Bash instantly exits, directly from the function scope - and since there is no ERR trap in effect there (because it wasn't inherited from the parent scope), your trap is not called.

    While the man page is not incorrect, I agree that this behavior is not exactly obvious - you have to infer it.

    0 讨论(0)
  • 2020-12-13 04:37

    Replace ERR with EXIT and it will work.

    The syntax of the trap command is: trap [COMMANDS] [SIGNALS]

    For more info, please read http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html

    0 讨论(0)
提交回复
热议问题