11

Does set -e behave differently here

set -e;

function foo {

}

vs.

function foo {
  set -e;

}

does set -e belong inside functions? Does set -e declared outside of functions, affect "nested" functions inside a shell file? What about the inverse? Should we call local set -e lol?

Alexander Mills
  • 9,330
  • 19
  • 95
  • 180
  • 4
    My advise ([and many's](http://mywiki.wooledge.org/BashFAQ/105)): don't use `set -e` in a script complex enough as to need functions. Do proper error handling instead. – Stéphane Chazelas Nov 18 '17 at 11:27

2 Answers2

11

Note: the statements here apply to Bash version 4.0.35 and up. Implementations of set -e vary wildly among different shells/versions. Follow Stéphane's advice and don't use set -e.

man bash in the Shell Builtin Commands/set section explains things pretty well though the text is a little dense and requires a bit of focus. To your specific questions the answers are:

  • Does set -e behave different here...vs.. - Depends on what you mean by "differently" but I suspect you'd consider the answer "no"...there are no tricky scoping rules. It acts quite linearlly.
  • Does set -e belong inside functions? - Perfectly valid.
  • Does set -e declared outside of functions, affect "nested" functions inside a shell file? - Yes
  • What about the inverse? - set -e in a function and then encounter a non-zero status after return? Yes, this will exit.
B Layer
  • 5,107
  • 1
  • 17
  • 34
  • 2
    There are complex rules that differ between versions. See http://mywiki.wooledge.org/BashFAQ/105 and linked pages for details. Best to stay away from `set -e`. – Stéphane Chazelas Nov 18 '17 at 11:35
  • will `set -e` inside a function affect the whole shell? Because this question - https://unix.stackexchange.com/questions/407385/any-command-in-my-terminal-that-exits-with-non-zero-code-closes-my-terminal-wind – Alexander Mills Nov 29 '17 at 01:18
  • Yes, that's what the fourth bullet indicates. Functions aren't isolated environments (discounting `local` vars). (If you ever use `set -x` to debug and put it in a function you'll see this in action.) Again, I've only tested with Bash 4.4... earlier (much earlier?) versions may have different behavior. – B Layer Nov 29 '17 at 03:55
0

Solution to avoid any headaches:

function foo {
  (
  set -e;
  )
}

(Just use a subshell).

Alexander Mills
  • 9,330
  • 19
  • 95
  • 180