简体   繁体   中英

How to determine whether a function exists in a POSIX shell?

This is basically the same question as Determine if a function exists in bash , except that this time it's not aiming at Bash, but at a POSIX shell :

How to determine whether a shell function with a given name exists?

It seems that none of the typical built-ins like type are mandated by POSIX, so the matter is more difficult or maybe even impossible.

You can use command for this in shells that implement the 2013 version of POSIX, or the User Portability Utilities option of the older spec:

isFunction() { 
  command -V "$1" 2>/dev/null | grep -qwi function
}

However, note that the spec doesn't actually dictate the form of the command's output. It requires that functions be identified as such, so it is highly likely that the output will include the word function if and only if the requested name is a function, but it is not strictly guaranteed. The above solution can be fooled pretty easily (see @jiliagre's comment).

A different part of the spec mandates a type command that does much the same thing (with the same caveats about unspecified output format). Oddly, it's not listed as one of the commands required to be a shell builtin, but as the informational notes say, it pretty much has to be one in order to work as specified.

POSIX (more precisely the X/Open Portability Guide ) specify the type command. It doesn't state what the type command should return to tell what the argument is. However, the standard says it typically identifies the operand, so it would be very unlikely for a type implementation not to include the string "function" in its reply when passed a function name.

This should then work with most, if not all, POSIX compliant shells:

isFunction()
{
    type "$1" | sed "s/$1//" | grep -qwi function
} 

You might also run command -V instead of type here, with the same comment about the unspecified output format. I never do, given the fact the former is shorter to type and easier to remember. This would, however, be mandatory if you run a shell that decided not to include XSI (likely posh ), ie, a shell that breaks portability with many existing scripts by limiting the utilities it tries to comply with to the strict POSIX set.

For the sake of completeness: it is possible to use type or command -V without spawning any extra subprocesses like sed or grep (although you still have to spawn one for $(type ...) ):

is_function() {
    case "$(type -- "$1" 2>/dev/null)" in
        *function*) return 0 ;;
    esac
    return 1
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM