1

Let's say I write a bash function like so:

function.sh

usage () {echo "No arguments are needed";}

myfunction () {

if [[ $# -qt 0 ]] ;
then
   usage
fi

echo "Hello World"
}

Then I source function.sh. However, I have another script with usage() defined there too and I have sourced it too.

I run myfunction -myWorld and I hit the usage() call and it calls the correct one somehow.

How does bash know which usage() to call?

8
  • 2
    whichever one is the most recently defined in the current shell context is the one that gets executed.
    – cas
    Commented Oct 20, 2021 at 15:23
  • @Jeff I'm afraid no. Do you mean that the other script is also sourced? If so, before or after function.sh?
    – AdminBee
    Commented Oct 20, 2021 at 15:25
  • 1
    if you mean "how do I ensure the right usage function gets called in any script?" then 1. don't redefine the function, don't source another script that you know is going to redefine the function, or 2. use different names for the functions in different scripts. a function name can only have one definition at a time. redefine it, and the old definition is replaced by the new.....same as what happens when you assign a new value to a variable. or 3. if you must source a script that defines usage(), then define the local version after sourcing that script.
    – cas
    Commented Oct 20, 2021 at 15:37
  • 1
    Does this answer your question? Bash source -- select the right function when two sourced files have the same function name? Commented Oct 20, 2021 at 15:38
  • 1
    just in case you're tempted to try, you can define a function within another function, but there's still no nested functions, e.g. this would redefine the global function bar every time foo runs: foo() { bar() { echo bb; }; echo ff; }
    – ilkkachu
    Commented Oct 20, 2021 at 16:00

2 Answers 2

2

The answer to your question, as it currently stands, is that Bash calls the last defined version of the function.

Using two modified versions of your example:

function1.sh

usage () { echo "Usage from function1.sh - No arguments are needed"; }

myfunction1 () {
  if [[ $# -gt 0 ]] ;
  then
    usage
  fi

  echo "Hello World"
}

function2.sh

usage () { echo "Usage from function2.sh - No arguments are needed"; }

myfunction2 () {
  if [[ $# -gt 0 ]] ;
  then
    usage
  fi

  echo "Hello World"
}

Then running

$ source function1.sh
$ source function2.sh
$ usage

will give the output

Usage from function2.sh - No arguments are needed

Note that in your script:

  • -qt should be -gt, and;
  • some spaces were missing in the usage() - around the echo
0
0

I don't want to deprive the poster above me as the correct answer, since he outright answered my question.

However, I do want to post a followup.

Instead of the function being sourced, I added the directory the function.sh lived in to PATH and renamed the file to myfunction. On the very last line of the file myfunction is myfunction $@.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .