Date: Wed, 12 Aug 2020 11:05:40 -0400 From: Eli Schwartz <eschwa...@archlinux.org> Message-ID: <f53f8a84-ac66-6d61-7066-01c14e8f2...@archlinux.org>
| When in posix mode, fname must be a valid shell name and may not be the | name of one of the POSIX special builtins. In default mode, a function | name can be any unquoted shell word that does not contain $. There's no need for the posix mode test here, in posix mode a function with the same name as a special builtin won't be found (the special builtin is located first) but it doesn't need to be an error to define it (posix does not require that). Further this works fine in bash, simply do something like set +o posix exec() { printf %s\\n 'exec called'; } exec /bin/sh set -o posix exec /bin/sh and watch what happens (it helps if /bin/sh is not bash, if it is, use something different to make it easier to determine what occurred). Further, posix permits extensions to the syntax for function names as an extension - applications cannot assume that anything which is not a name (as defined) will work in any arbitrary conformant shell, but there is no requirement on the shell validate that function names are "name"s in the POSIX sense (it is of course allowed for them to do so). For extended function names, a shell can allow what it likes, so "everything except '$') is certainly permitted. I'm not sure why '$' needs to be prohibited though (unless it is just to avoid the noise from people who don't understand why things aren't doing what they expecr), in func$3() { command-list; } the '$' is not expanded, no word expansions happen to the function name in a function definition, and while func$3 arg will certainly not invoke that function ($3 would be expanded there), func\$3 arg would invoke it (or 'func$3' or $'func$3' or whatever). Going the other way, it might make some sense however to prohibit '/' in a function name, as there is truly no way to invoke such a function, any command name containing a '/' anywhere bypasses all that part of the lookup process and is simply exec()'d via the filesystem. kre