From documentation of set -e
:
When this option is on, if a simple command fails for any of the
reasons listed in Consequences of
Shell Errors or returns an exit status
value > 0, and is not part of the
compound list following awhile
,
until
, orif
keyword, and is not a
part of anAND
orOR
list, and is not
a pipeline preceded by the!
reserved
word, then the shell shall immediately
exit.
In your case, false
is a part of a pipeline preceded by !
and a part of if
. So the solution is to rewrite your code so that it isn’t.
In other words, there’s nothing special about functions here. Try:
set -e
! { false; echo hi; }