确定bash中是否存在函数

时间:2020-03-05 18:59:32  来源:igfitidea点击:

目前,我正在做一些从bash执行的单元测试。单元测试是在bash脚本中初始化,执行和清理的。该脚本通常包含init(),execute()和cleanup()函数。但是它们不是强制性的。我想测试一下是否定义了它们。

之前,我是通过摸索和诱骗来源来做到这一点的,但这似乎是错误的。有没有更优雅的方法可以做到这一点?

编辑:以下代码段就像一个超级按钮一样工作:

fn_exists()
{
    type  | grep -q 'shell function'
}

解决方案

回答

我认为我们正在寻找"类型"命令。它会告诉我们某些东西是函数,内置函数,外部命令还是只是未定义。例子:

$ type foo
bash: type: foo: not found

$ type ls
ls is aliased to `ls --color=auto'

$ which type

$ type type
type is a shell builtin

$ type -t rvm
function

$ if [ -n "$(type -t rvm)" ] && [ "$(type -t rvm)" = function ]; then echo rvm is a function; else echo rvm is NOT a function; fi
rvm is a function

回答

$ g() { return; }
$ declare -f g > /dev/null; echo $?
0
$ declare -f j > /dev/null; echo $?
1

回答

我将其改进为:

fn_exists()
{
    type  2>/dev/null | grep -q 'is a function'
}

并像这样使用它:

fn_exists test_function
if [ $? -eq 0 ]; then
    echo 'Function exists!'
else
    echo 'Function does not exist...'
fi

回答

这告诉我们它是否存在,但不是它是一个函数

fn_exists()
{
  type  >/dev/null 2>&1;
}

回答

疏通旧帖子...但是我最近使用了它,并测试了以下描述的两种替代方法:

test_declare () {
    a () { echo 'a' ;}

    declare -f a > /dev/null
}

test_type () {
    a () { echo 'a' ;}
    type a | grep -q 'is a function'
}

echo 'declare'
time for i in $(seq 1 1000); do test_declare; done
echo 'type'
time for i in $(seq 1 100); do test_type; done

这产生了:

real    0m0.064s
user    0m0.040s
sys     0m0.020s
type

real    0m2.769s
user    0m1.620s
sys     0m1.130s

声明是helluvalot更快!

回答

可以使用'type'而不使用任何外部命令,但是我们必须调用它两次,因此它的运行速度仍然是'declare'版本的两倍:

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

另外,这在POSIX sh中不起作用,因此,除了琐事之外,它完全不值钱!