14

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?

1
  • 4
    My advise (and many's): don't use set -e in a script complex enough as to need functions. Do proper error handling instead. Nov 18, 2017 at 11:27

2 Answers 2

13

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.
3
  • 2
    There are complex rules that differ between versions. See mywiki.wooledge.org/BashFAQ/105 and linked pages for details. Best to stay away from set -e. Nov 18, 2017 at 11:35
  • will set -e inside a function affect the whole shell? Because this question - unix.stackexchange.com/questions/407385/… Nov 29, 2017 at 1: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, 2017 at 3:55
-2

Solution to avoid any headaches:

function foo {
  (
       set -e;
  )
}

(Just use a subshell). Sometimes to make it both confusing and pretty, I do this:

 function foo {(
      set -e;
      # the rest goes here
  )}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .