目前我正在做一些从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()
{
   [[ $(type -t $1) == function ]] && return 0
}

更新

isFunc () 
{ 
    [[ $(type -t $1) == function ]]
}

$ isFunc isFunc
$ echo $?
0
$ isFunc dfgjhgljhk
$ echo $?
1
$ isFunc psgrep && echo yay
yay
$

可以在没有任何外部命令的情况下使用'type',但你必须调用它两次,所以它的速度仍然是'declare'版本的两倍:

test_function () {
        ! type -f $1 >/dev/null 2>&1 && type -t $1 >/dev/null 2>&1
}

加上这不能在POSIX sh中工作,所以它完全没有价值,除了作为琐事!

如果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

我特别喜欢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;
}