Configuration Information [Automatically generated, do not change]: Machine: i486 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall uname output: Linux cargocult 2.6.20-16-generic #2 SMP Sun Sep 23 19:50:39 UTC 2007 i686 GNU/Linux Machine Type: i486-pc-linux-gnu
Bash Version: 3.2 Patch Level: 13 Release Status: release Description: Whether orr not ERR traps get invoked for failed simple commands inside a function depends on whether or not the error status is to be ignored for any function invocation in the call stack leading to the current function. This makes it practically impossible to reliably use ERR traps for error handling inside functions. This affects the -e option as well. The documentation isn't clear on what the behaviour should be -- is every command inside a function considered to be "part of" all command lists that directly or indirectly invoke the function? This would mean that a function cannot rely on a failed simple command behaving in any particular way -- to write a function that can handle this robustly, every command would have to be suffixed with either || true or || return. Unfortunately the situation is not as easy for -e: If a simple command failure inside a function caused the entire shell to terminate, any attempt by the caller to catch failures of that function would be ignored. It seems the most desirable behaviour would be to have a mode where a failed simple command causes the current function to propagate the status of the failed command to the caller. Repeat-By: bash -c 'set -E; trap "echo ERR" ERR; f() { false; }; g() { f; } ; g; echo -; g || true' Output: ERR ERR ERR - Expected ERR ERR ERR - ERR ERR Fix: Don't propagate CMD_IGNORE_RETURN into function invocations. *** execute_cmd.c.orig 2007-11-12 15:10:54.000000000 +1300 --- execute_cmd.c 2007-11-12 15:55:52.000000000 +1300 *************** *** 3192,3199 **** #endif tc = (COMMAND *)copy_command (function_cell (var)); - if (tc && (flags & CMD_IGNORE_RETURN)) - tc->flags |= CMD_IGNORE_RETURN; if (subshell == 0) { --- 3192,3197 ----