是否有内置(或至少简单)的方法来检查是否存在可通过 $FPATH 访问的函数?

是否有内置(或至少简单)的方法来检查是否存在可通过 $FPATH 访问的函数?

我想foo在脚本中定义一个函数(旨在来源),但前提是某些可执行文件、shell 内置函数、函数或该名称的别名尚未“存在”。

在这种情况下,“存在”的定义并不完全是微不足道的(因此是恐吓引号)。

作为第一个近似,我的操作定义是,foo如果which foo返回 以外的内容,则存在foo not found。这适用于我感兴趣的大多数情况......

% which cat
/bin/cat
% which cd
cd: shell built-in command
% which zargs
zargs () {
    # undefined
    builtin autoload -XU
}
% which grep
grep: aliased to grep --color=always

...但它不会捕获可通过以下方式访问的文件中定义的函数$FPATH

% which zargs
zargs not found

当然,我可以滚动我自己的包装器which来检查下面的函数$FPATH(通过显式迭代它等),但我已经了解到(或者可能过度学习),当涉及到 shell 编程时,没有什么是就像看起来一样简单......因此,如果已经存在 1)一种内置方法来执行可用函数的存在性测试;或者至少 2)这样做的既定习惯,我更愿意走那条路。

答案1

可通过访问的函数fpath并不“存在”,因为它可以被调用。它必须首先自动加载,之后which(以及测试函数是否存在的任何其他方法)将报告自动加载真实定义的存根定义。

% zargs
zsh: command not found: zargs
% autoload zargs
% which zargs
zargs () {
        # undefined
        builtin autoload -X
}

which foo准确测试是否foo可以用作命令名称,除了任何command_not_found_handler可能做的事情。由于command_not_found_handler可以包含任意代码,因此无法预测它会做什么;并且由于它在找到替代命令时执行替代命令,因此无法在不执行任何操作的情况下检查它会做什么。

如果您的代码是特定于 zsh 的,您可以使用whence而不是which(或者whence -w为了获得更简洁的输出,没有选项使其保持沉默),它是whence.如果您希望您的代码可在其他 Bourne/POSIX 风格的 shell 中使用,请使用type,而不是which

function exists {
  whence -w $1 >/dev/null
}

如果您对“存在”的定义包括可能会自动加载但尚未自动加载的函数,那么请实现检测可能会自动加载但尚未自动加载的函数的代码:$fpath显式遍历。

相关内容