autoconf: Shell Functions

1 
1 11.13 Shell Functions
1 =====================
1 
1 Nowadays, it is difficult to find a shell that does not support shell
1 functions at all.  However, some differences should be expected.
1 
1    When declaring a shell function, you must include whitespace between
1 the `)' after the function name and the start of the compound
1 expression, to avoid upsetting `ksh'.  While it is possible to use any
1 compound command, most scripts use `{...}'.
1 
1      $ /bin/sh -c 'a(){ echo hi;}; a'
1      hi
1      $ ksh -c 'a(){ echo hi;}; a'
1      ksh: syntax error at line 1: `}' unexpected
1      $ ksh -c 'a() { echo hi;}; a'
1      hi
1 
1    Inside a shell function, you should not rely on the error status of a
1 subshell if the last command of that subshell was `exit' or `trap', as
1 this triggers bugs in zsh 4.x; while Autoconf tries to find a shell
1 that does not exhibit the bug, zsh might be the only shell present on
1 the user's machine.
1 
1    Likewise, the state of `$?' is not reliable when entering a shell
1 function.  This has the effect that using a function as the first
1 command in a `trap' handler can cause problems.
1 
1      $ bash -c 'foo() { echo $?; }; trap foo 0; (exit 2); exit 2'; echo $?
1      2
1      2
1      $ ash -c 'foo() { echo $?; }; trap foo 0; (exit 2); exit 2'; echo $?
1      0
1      2
1 
1    DJGPP bash 2.04 has a bug in that `return' from a shell function
1 which also used a command substitution causes a segmentation fault.  To
1 work around the issue, you can use `return' from a subshell, or
1 `AS_SET_STATUS' as last command in the execution flow of the function
1 (⇒Common Shell Constructs).
1 
1    Not all shells treat shell functions as simple commands impacted by
1 `set -e', for example with Solaris 10 `/bin/sh':
1 
1      $ bash -c 'f() { return 1; }; set -e; f; echo oops'
1      $ /bin/sh -c 'f() { return 1; }; set -e; f; echo oops'
1      oops
1 
1    Shell variables and functions may share the same namespace, for
1 example with Solaris 10 `/bin/sh':
1 
1      $ f () { :; }; f=; f
1      f: not found
1 
1 For this reason, Autoconf (actually M4sh, ⇒Programming in M4sh)
1 uses the prefix `as_fn_' for its functions.
1 
1    Handling of positional parameters and shell options varies among
1 shells.  For example, Korn shells reset and restore trace output (`set
1 -x') and other options upon function entry and exit.  Inside a function,
1 IRIX sh sets `$0' to the function name.
1 
1    It is not portable to pass temporary environment variables to shell
1 functions.  Solaris `/bin/sh' does not see the variable.  Meanwhile,
1 not all shells follow the Posix rule that the assignment must affect
1 the current environment in the same manner as special built-ins.
1 
1      $ /bin/sh -c 'func() { echo $a;}; a=1 func; echo $a'
1      =>
1      =>
1      $ ash -c 'func() { echo $a;}; a=1 func; echo $a'
1      =>1
1      =>
1      $ bash -c 'set -o posix; func() { echo $a;}; a=1 func; echo $a'
1      =>1
1      =>1
1 
1    Some ancient Bourne shell variants with function support did not
1 reset `$I, I >= 0', upon function exit, so effectively the arguments of
1 the script were lost after the first function invocation.  It is
1 probably not worth worrying about these shells any more.
1 
1    With AIX sh, a `trap' on 0 installed in a shell function triggers at
11 function exit rather than at script exit.  ⇒Limitations of Shell
 Builtins trap.
1