Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override a shell function, keep a reference to the original one

Tags:

shell

posix

Is it possible to override a shell function and keep a reference to the original one?

f()  { echo original; }
f()  { echo wrapper; ...; }
f

The output of this should be:

wrapper
original

Is this possible in a semi-portable way?

Rationale: I'm trying to test my program by replacing parts of it with shell functions which record their calls into a log file. This works fine as long as I only wrap commands and builtins, and as long as I don't mind indiscriminate logging. Now I'd like to make the test suite more maintainable by only recording the interesting piece in each test.

So let's say my program consists of

f
g
h

where f, g, h are all shell functions, and I'd like to trace the execution of just g.

like image 710
just somebody Avatar asked May 27 '13 13:05

just somebody


2 Answers

The answer by Jens is correct. Just adding below code for completeness.

You can simply use it as below:

eval "`declare -f f | sed '1s/.*/_&/'`" #backup old f to _f

f(){
    echo wrapper
    _f # pass "$@" to it if required.
}

I had used same logic here: https://stackoverflow.com/a/15758880/793796

like image 159
anishsane Avatar answered Oct 23 '22 08:10

anishsane


Many shells (zsh, ksh, bash at least) support typeset -f f to dump the contents of f(). Use this to save the current definition to a file; then, define f() as you want. Restore f() by sourcing the file created with typeset.

If you slightly modify the dumped function (renaming f() to _f() on the first line; a bit trickier when f() is recursive or calls other functions you frobbed in the same way), you can likely get this to produce the output you desired.

like image 39
Jens Avatar answered Oct 23 '22 07:10

Jens