Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I rename a bash function?

Tags:

function

bash

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?

like image 557
Carl Meyer Avatar asked Jul 29 '09 23:07

Carl Meyer


People also ask

How do you declare a function in bash?

The syntax for declaring a bash function is straightforward. Functions may be declared in two different formats: The first format starts with the function name, followed by parentheses. This is the preferred and more used format.

What is f flag in bash?

The -f flag verifies two things: the provided path exists and is a regular file. If /etc/bashrc is in fact a directory or missing, test should return non-zero exit status to signal failure.


2 Answers

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 
like image 56
Evan Broder Avatar answered Sep 20 '22 22:09

Evan Broder


Further golfed the copy_function and rename_function functions to:

copy_function() {   test -n "$(declare -f "$1")" || return    eval "${_/$1/$2}" }  rename_function() {   copy_function "$@" || return   unset -f "$1" } 

Starting from @Dmitri Rubinstein's solution:

  • No need to call declare twice. Error checking still works.
  • Eliminate temp var (func) by using the _ special variable.
    • Note: using test -n ... was the only way I could come up with to preserve _ and still be able to return on error.
  • Change return 1 to return (which returns the current status code)
  • Use a pattern substitution rather than prefix removal.

Once copy_function is defined, it makes rename_function trivial. (Just don't rename copy_function;-)

like image 41
ingydotnet Avatar answered Sep 17 '22 22:09

ingydotnet