Can a function be extended in Bash?

If I define a function in a file, say test1.sh :

#!/bin/bash

foo() {
    echo "foo"
}

      

And in the second test2.sh , I try to override foo

:

#!/bin/bash

source /path/to/test1.sh    
...
foo() {
    ...
    echo "bar"
}
foo

      

Is there a way to modify test2.sh to build:

foo
bar

      

I know it is command

possible to use Bash intrinsic functions with, but I want to know if a user function can be extended?

+3


source to share


3 answers


I'm not sure if I see a need to do something like this. You can use functions inside functions, so why use a name when you can just call the original original function in the newly created function like this:

AirBoxOmega:stack d$ cat source.file
#!/usr/local/bin/bash

foo() {
    echo "foo"
}
AirBoxOmega:stack d$ cat subfoo.sh
#!/usr/local/bin/bash


source /Users/d/stack/source.file
sub_foo() {
  foo
  echo "bar"
}

sub_foo
AirBoxOmega:stack d$ ./subfoo.sh
foo
bar

      



Of course, if you have your heart REALLY set up to modify, you can specify your function inside a new function, call it and then do something esle after, like:

AirBoxOmega:stack d$ cat source.file
#!/usr/local/bin/bash

foo() {
    echo "foo"
}
AirBoxOmega:stack d$ cat modify.sh
#!/usr/local/bin/bash


foo() {
  source /Users/d/stack/source.file
  foo
  echo "bar"
}

foo
AirBoxOmega:stack d$ ./modify.sh
foo
bar

      

+1


source


I don't know of a good way to do this (but I'd really like to be proven wrong).

Here's an ugly way:



# test2.sh
# ..
eval 'foo() {
        '"$(declare -f foo | tail -n+2)"'

        echo bar
      }'

      

+3


source


No, It is Immpossible. The new declaration will override the previous function instance. But even though you don't have this option, it's still useful when you want to disable a feature without having to undo it:

foo() {
    :  ## Do nothing.
}

      

This is also useful for lazy initializations:

foo() {
    # Do initializations.
    ...

    # New declaration.
    if <something>; then
        foo() {
            ....
        }
    else
        foo() {
            ....
        }
    fi

    # Call normally.
    foo "$@"
}

      

And if you are brave and capable enough to use eval

, you can even optimize your function to work without additional if

conditional based.

+2


source







All Articles