目前我正在做一些从bash执行的单元测试。单元测试在bash脚本中初始化、执行和清理。该脚本通常包含init()、execute()和cleanup()函数。但它们不是强制性的。我想测试它们是否有定义。
我以前通过greping和seding源代码做到了这一点,但这似乎是错误的。还有更优雅的方式吗?
编辑:下面这句话很有魔力:
fn_exists()
{
LC_ALL=C type $1 | grep -q 'shell function'
}
目前我正在做一些从bash执行的单元测试。单元测试在bash脚本中初始化、执行和清理。该脚本通常包含init()、execute()和cleanup()函数。但它们不是强制性的。我想测试它们是否有定义。
我以前通过greping和seding源代码做到了这一点,但这似乎是错误的。还有更优雅的方式吗?
编辑:下面这句话很有魔力:
fn_exists()
{
LC_ALL=C type $1 | grep -q 'shell function'
}
当前回答
如果declare比test快10倍,这似乎是显而易见的答案。
编辑:下面,-f选项在BASH中是多余的,可以省略它。就我个人而言,我很难记住哪个选项能做哪个,所以我两种都用。-f显示函数,-f显示函数名。
#!/bin/sh
function_exists() {
declare -f -F $1 > /dev/null
return $?
}
function_exists function_name && echo Exists || echo No such function
要声明的“-F”选项导致它只返回找到的函数的名称,而不是整个内容。
使用/dev/null不应该有任何可衡量的性能损失,如果您如此担心:
fname=`declare -f -F $1`
[ -n "$fname" ] && echo Declare -f says $fname exists || echo Declare -f says $1 does not exist
或者把两者结合起来,只为你自己毫无意义的享受。它们都有效。
fname=`declare -f -F $1`
errorlevel=$?
(( ! errorlevel )) && echo Errorlevel says $1 exists || echo Errorlevel says $1 does not exist
[ -n "$fname" ] && echo Declare -f says $fname exists || echo Declare -f says $1 does not exist
其他回答
来自我对另一个答案的评论(当我回到这个页面时,我总是忽略这个答案)
$ fn_exists() { test x$(type -t $1) = xfunction; }
$ fn_exists func1 && echo yes || echo no
no
$ func1() { echo hi from func1; }
$ func1
hi from func1
$ fn_exists func1 && echo yes || echo no
yes
fn_exists()
{
[[ $(type -t $1) == function ]] && return 0
}
更新
isFunc ()
{
[[ $(type -t $1) == function ]]
}
$ isFunc isFunc
$ echo $?
0
$ isFunc dfgjhgljhk
$ echo $?
1
$ isFunc psgrep && echo yay
yay
$
我特别喜欢Grégory Joseph的解决方案
但我对它做了一点修改,以克服“双引号丑陋的把戏”:
function is_executable()
{
typeset TYPE_RESULT="`type -t $1`"
if [ "$TYPE_RESULT" == 'function' ]; then
return 0
else
return 1
fi
}
你可以用四种方法检查它们
fn_exists() { type -t $1 >/dev/null && echo 'exists'; }
fn_exists() { declare -F $1 >/dev/null && echo 'exists'; }
fn_exists() { typeset -F $1 >/dev/null && echo 'exists'; }
fn_exists() { compgen -A function $1 >/dev/null && echo 'exists'; }
这告诉你它是否存在,但不是说它是一个函数
fn_exists()
{
type $1 >/dev/null 2>&1;
}