tags:

views:

310

answers:

2

I am developing some convenience wrappers around another software package that defines a bash function. I would like to replace their bash function with an identically-named function of my own, while still being able to run their function from within mine. In other words, I need to either rename their function, or create some kind of persistent alias to it that won't be modified when I create my function of the same name.

To give a brief example of a naive attempt that I didn't expect to work (and indeed it does not):

$ theirfunc() { echo "do their thing"; }
$ _orig_theirfunc() { theirfunc; }
$ theirfunc() { echo "do my thing"; _orig_theirfunc }
$ theirfunc
do my thing
do my thing
do my thing
...

Obviously I don't want infinite recursion, I want:

do my thing
do their thing

How can I do this?

+3  A: 

Aha. Found a solution, though it's not real pretty:

$ theirfunc() { echo "do their thing"; }
$ echo "orig_theirfunc()" > tmpfile
$ declare -f theirfunc | tail -n +2 >> tmpfile
$ source tmpfile
$ theirfunc() { echo "do my thing"; orig_theirfunc; }
$ theirfunc
do my thing
do their thing

I'm sure this could be improved by a real bash wizard. In particular it'd be nice to ditch the need for a tempfile.

Update: bash wizard Evan Broder rose to the challenge (see accepted answer above). I reformulated his answer into a generic "copy_function" function:

# copies function named $1 to name $2
copy_function() {
    declare -F $1 > /dev/null || return 1
    eval "$(echo "${2}()"; declare -f ${1} | tail -n +2)"
}

Can be used like so:

$ theirfunc() { echo "do their thing"; }
$ copy_function theirfunc orig_theirfunc
$ theirfunc() { echo "do my thing"; orig_theirfunc; }
$ theirfunc
do my thing
do their thing

Very nice!

Carl Meyer
Bash inheritance! I never thought I'd see the day.
brownstone
+6  A: 

Here's a way to eliminate the temp file:

$ theirfunc() { echo "do their thing"; }
$ eval "$(echo "orig_theirfunc()"; declare -f theirfunc | tail -n +2)"
$ theirfunc() { echo "do my thing"; orig_theirfunc; }
$ theirfunc
do my thing
do their thing
Evan Broder
Brilliant! Thank you, bash wizard ;-)
Carl Meyer