views:

2310

answers:

6

Currently I'm doing some unit tests which are executed from bash. Unit tests are initialized, executed and cleaned up in a bash script. This script usualy contains an init(), execute() and cleanup() functions. But they are not mandatory. I'd like to test if they are or are not defined.

I did this previously by greping and seding the source, but it seemed wrong. Is there a more elegant way to do this?

Edit: The following sniplet works like a charm:

fn_exists()
{
    type $1 | grep -q 'shell function'
}
+17  A: 

I think you're looking for the 'type' command. It'll tell you whether something is a function, built-in function, external command, or just not defined. Example:

batzel@batzel-laptop:~$ type foo
bash: type: foo: not found
batzel@batzel-laptop:~$ type ls
ls is aliased to `ls --color=auto'
batzel@batzel-laptop:~$ which type
batzel@batzel-laptop:~$ type type
type is a shell builtin
JBB
`type -t $function` is the meal ticket.
Allan Wind
Why didn't you post it as an answer? :-)
terminus
Because I had posted my answer using declare first :-)
Allan Wind
Why not rewrite it?
terminus
+3  A: 
$ g() { return; }
$ declare -f g > /dev/null; echo $?
0
$ declare -f j > /dev/null; echo $?
1
Allan Wind
A: 

I would improve it to:

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

And use it like this:

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

Dredging up an old post ... but I recently had use of this and tested both alternatives described with :

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

this generated :

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

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

declare is a helluvalot faster !

delerious010
Of course, since you're not calling grep in the first one.
terminus
A: 

It is possible to use 'type' without any external commands, but you have to call it twice, so it still ends up about twice as slow as the 'declare' version:

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

Plus this doesn't work in POSIX sh, so it's totally worthless except as trivia!

Noah Spurrier