目前我正在做一些从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'
}
当前回答
这告诉你它是否存在,但不是说它是一个函数
fn_exists()
{
type $1 >/dev/null 2>&1;
}
其他回答
函数的调用(如果已定义)。
已知函数名。假设名称是my_function,然后使用
[[ "$(type -t my_function)" == 'function' ]] && my_function;
# or
[[ "$(declare -fF my_function)" ]] && my_function;
函数名存储在一个变量中。如果我们声明func=my_function,那么我们可以使用
[[ "$(type -t $func)" == 'function' ]] && $func;
# or
[[ "$(declare -fF $func)" ]] && $func;
||代替&&也有同样的结果 (这样的逻辑反转在编码过程中很有用)
[[ "$(type -t my_function)" != 'function' ]] || my_function;
[[ ! "$(declare -fF my_function)" ]] || my_function;
func=my_function
[[ "$(type -t $func)" != 'function' ]] || $func;
[[ ! "$(declare -fF $func)" ]] || $func;
严格的模式和前提条件检查 我们将-e设置为严格模式。 在先决条件下,我们在函数中使用|| return。 这将迫使我们的shell进程终止。
# Set a strict mode for script execution. The essence here is "-e"
set -euf +x -o pipefail
function run_if_exists(){
my_function=$1
[[ "$(type -t $my_function)" == 'function' ]] || return;
$my_function
}
run_if_exists non_existing_function
echo "you will never reach this code"
以上是等价的
set -e
function run_if_exists(){
return 1;
}
run_if_exists
这会终止您的流程。 使用|| {true;返回;}而不是||返回;在前提条件下解决这个问题。
[[ "$(type -t my_function)" == 'function' ]] || { true; return; }
我特别喜欢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 $1 >/dev/null 2>&1;
}
你可以用四种方法检查它们
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'; }
可以在没有任何外部命令的情况下使用'type',但你必须调用它两次,所以它的速度仍然是'declare'版本的两倍:
test_function () {
! type -f $1 >/dev/null 2>&1 && type -t $1 >/dev/null 2>&1
}
加上这不能在POSIX sh中工作,所以它完全没有价值,除了作为琐事!