如何确定某个函数是否已在 bash 脚本中定义?
我正在尝试使我的 .bash_login 脚本在系统之间可移植,因此我想添加逻辑以仅在函数存在时才调用它。
仅当该系统上存在该功能时,我__git_ps1()才想添加。PS1这个函数通常在git-completion.bashgit 源中定义,或者由 ports/apt 安装的 bash 完成脚本之一定义。
我意识到这是一个老问题,但没有其他答案能像我想要的那样简单。这使用type -t(如 Chen Levy 的评论中所建议的)作为一种有效的测试类型,但随后使用 shell 字符串比较而不是调用 grep。
if [ "$(type -t somefunc)" = 'function' ]; then
somefunc arg1 arg2
fi
更进一步,它也间接地起作用:
funcname=do_it_special_$somehow
if [ "$(type -t $funcname)" != 'function' ]; then
funcname=do_it_normal
fi
$funcname arg1 arg2
if type __git_ps1 | grep -q '^function$' 2>/dev/null; then
PS1=whatever
fi
您可以使用:
type function_name
in 将返回您的函数定义,以防它存在。因此,您可以检查输出是否为空。
PS。更好的是,我刚刚检查过它将输出该函数不存在,否则输出函数体。
如果您需要/bin/sh兼容的版本,则不能使用typeset或declare测试函数定义,因为它不是内置的 shell。此外,在某些系统上可能不提供该-f选项。type
我提出的解决方案已经部分包含在其他答案中:
isFunction() {
type $1 | head -1 | egrep "^$1.*function\$" >/dev/null 2>&1;
return;
}
isFunction __git_ps1 && PS1=__git_ps1
声明 -F 'function_name' > /dev/null
回声$?
美元?如果函数存在,则结果值为 0,否则为 1
我认为最好使用声明,即使它比类型稍慢。还为 PATH 中的别名或脚本键入 suceeds。
我正在使用这个:
function function_exists
{
FUNCTION_NAME=$1
[ -z "$FUNCTION_NAME" ] && return 1
declare -F "$FUNCTION_NAME" > /dev/null 2>&1
return $?
}
所以稍后在我的脚本中,我可以很容易地看到发生了什么:
if function_exists __git_ps1
then
PS1=__git_ps1
fi
甚至是仍然可读的单行:
function_exists __git_ps1 && PS1=__git_ps1
您可以列出所有可用的函数或使用 compgen 检查单个函数:
help compgen
compgen -A function
compgen -A function myfunc 1>/dev/null && echo 'myfunc already exists' || exit 1
if declare -F | grep __git_ps1$
then
PS1=whatever
fi
请注意,busybox(极简的多合一 shell 实现,例如在 Windows 上很有用)具有“type”但“type -t”打印错误的内容,所以我只检查 type 的返回值以查看是否有可调用的内容。busybox 也没有声明。