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
bash


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 to share


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 to share


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 to share







All Articles
Loading...
X
Show
Funny
Dev
Pics