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