简体   繁体   English

如何确定POSIX shell中是否存在函数?

[英]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 : 这与确定函数是否存在于bash中的问题基本相同,除了这次它不是针对Bash,而是针对POSIX shell

How to determine whether a shell function with a given name exists? 如何确定具有给定名称的shell函数是否存在?

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. 似乎POSIX没有规定像type这样的典型内置函数,所以问题更难或甚至不可能。

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: 您可以在实现2013版POSIX的shell或旧版规范的User Portability Utilities选项中使用command

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. 它需要的功能被确定为这样的,所以这是非常有可能的是,输出将包括单词function ,当且仅当请求的名称是一个函数,但它不是严格的保证。 The above solution can be fooled pretty easily (see @jiliagre's comment). 上述解决方案很容易被愚弄(参见@ jiliagre的评论)。

A different part of the spec mandates a type command that does much the same thing (with the same caveats about unspecified output format). 规范的另一部分要求type命令执行大致相同的操作(对于未指定的输出格式具有相同的警告)。 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. 奇怪的是,它并没有被列为shell内置所需的命令之一,但正如信息性说明所说,它几乎必须是一个才能按指定的方式工作。

POSIX (more precisely the X/Open Portability Guide ) specify the type command. POSIX(更准确地说是X / Open可移植性指南 )指定了type命令。 It doesn't state what the type command should return to tell what the argument is. 它没有说明应该返回什么type命令来告诉参数是什么。 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. 但是,标准说它通常标识操作数,因此type实现不太可能在传递函数名时不在其回复中包含字符串“function”。

This should then work with most, if not all, POSIX compliant shells: 这应该适用于大多数(如果不是全部)POSIX兼容的shell:

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. 您也可以在此处运行command -V而不是type ,并对未指定的输出格式使用相同的注释。 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. 但是,如果你运行一个决定不包含XSI(可能是posh )的shell,那就是强制性的,即shell通过限制它试图遵守严格的POSIX集的实用程序来破坏许多现有脚本的可移植性。

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 ...) ): 为了完整起见:可以使用typecommand -V而不产生任何额外的子进程,如sedgrep (尽管你仍然需要为$(type ...)生成一个):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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