如何判断bash脚本中函数是否已定义?
我正在尝试使我的.bash_login脚本在各个系统间可移植,因此我想添加逻辑仅在该函数存在时调用它。
我希望仅当该系统上存在__git_ps1()
函数时才将其添加到PS1
中。该函数通常在git-completion.bash
(随git源代码提供)或其中一个端口/ 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
比 declare
更快 - 谢谢。 - csexton__get_ps1
是别名、内置命令等,它也会返回“true”。使用if type -t function_name | grep -q "^function$";then ... fi
,确保__git_ps1
是一个函数。 - Chen Levygrep
命令;只需运行 type
命令,该命令将返回类型是否存在的真/假值。而且,无论您是否使用 type -t
命令都没有太大关系;如果已定义(标准的)__git_ps1
,那么这可能是您想要用于 PS1 提示符的内容,无论它是如何定义的;即,if type __git_ps1 > /dev/null 2>&1 ; then PS1='\n\w $(__git_ps1)\n\!$ '; fi
。 - michael您可以使用以下方法进行操作:
type function_name
如果存在函数定义,in将返回一个函数定义。因此,您可以检查输出是否为空。
附注:更好的是,我刚刚检查它会输出函数不存在,否则输出函数主体。
/bin/sh
的版本,您不能使用 typeset
或 declare
来测试函数定义,因为它不是shell内置命令。此外,type
命令的 -f
选项可能在某些系统上不可用。isFunction() {
type $1 | head -1 | egrep "^$1.*function\$" >/dev/null 2>&1;
return;
}
isFunction __git_ps1 && PS1=__git_ps1
declare -F 'function_name' > /dev/null
echo $?
如果该函数存在,则$?的值为0,否则为1。
我认为最好使用declare,即使它比type稍微慢一些。Type也适用于别名或在PATH中的脚本。
我正在使用以下内容:
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
"$(type -t somefunc)"
而不是反引号。 - wisbucky-t
参数应该始终被提供。这样可以解决问题,无论本地化如何。也就是说这是唯一正确的方式。或者查看退出代码。 - Melroy van den Berg