Bash function renaming and overriding
One annoyance I found when writing bash scripts is the lack of function references. This became apparent when overriding a function, but when I wanted to change the behavior only slightly. I had a library of functions, and wanted to add some commands before the start of the function, and some cleanup code immediately after it finished.
This being a library function that was called elsewhere, I couldn’t edit the function in the library itself. Nor could I edit the calling code and add the steps before and after - the calling code was itself another library function. This left the option of copying and pasting the entire function, and adding my extra code to the beginning and end.
In python (and many other languages), I would have done something like the following:
old_foo = foo
def foo():
initialization_code()
old_foo()
cleanup_code()
but bash doesn’t seem to support function references in that manner. After
much searching however, I finally found a way to save a function under a new
name, which gives the same kind of functionality using bash’s declare
builtin.
The declare
command prints out the values of declared variables, and more
importantly, declared functions - declare -f foo
will print out the code
for function foo
. So all you need to do is execute the output of the
declare -f
command, after substituting the name of the function. The
following bash function does just this:
save_function() {
local ORIG_FUNC=$(declare -f $1)
local NEWNAME_FUNC="$2${ORIG_FUNC#$1}"
eval "$NEWNAME_FUNC"
}
Add that to your scripts, and you have a simple way to copy/rename a function, and a simple way to add a step before/after an existing function. To copy the python example above:
save_function foo old_foo
foo() {
initialization_code()
old_foo()
cleanup_code()
}
Now any code calling foo in the script will get the new behavior.