3

In the scenario where both script1.sh and script2.sh contain a function with the same name but different definitions, and script2.sh is sourced in script1.sh, if the function is executed from script1.sh. Which function will be invoked?

I tried to simulate this case. If the function is executed from script1.sh, it is using the function defined in script1.sh only. However, is this behavior consistent across all cases?

script1.sh

#!/bin/bash
source script2.sh
execute() {
    echo "Hello"
}
execute

script2.sh

#!/bin/bash
execute() {
   echo "Something"
}
4
  • Please find the edited question for your reference. In my scenario, script2.sh will be sourced before executing the function.
    – manasa
    Apr 1 at 11:48
  • @manasa …but also before (re)defining the function in the main script. Apr 1 at 12:14
  • While Stéphane Chazelas addresses a cool method to namespace functions in shell scripts, I personally advise switching to a more capable scripting language (Python / Perl / whatever) the moment namespaces are needed, and that is probably a bit too late already...
    – kos
    Apr 2 at 5:33
  • source is more like the C preprocessor #include directive than it is like an import statement.
    – chepner
    Apr 2 at 12:54

2 Answers 2

15

You can think of the function as a variable in this context: it will have the last value you assigned it. Just like if you have something like this:

var=foo
var=bar
var=baz
echo "$var"

In the case above, I hope it is obvious that echo "$var" will print out baz since every time you assign a value to a variable you overwrite whatever value it might have had before. Functions work in the same way. If you define a function with the same name multiple times, only the last definition will be relevant and the others will be lost.

Sourcing doesn't change that. If you source a function from a file and then redefine a new function with the same name, then only the new one will work. Conversely, if you define a function in your script and then source a file with a function of the same name, only the sourced one will work.

So yes, it is entirely consistent, the order of operations defines what will actually be used.

3
  • 1
    The technical term for this is dynamic scoping. Apr 1 at 13:51
  • 5
    @reinierpost, I don't think there are scopes for functions (in Bash or a POSIX shell). Just the global scope.
    – ilkkachu
    Apr 1 at 13:58
  • Yes, 'no scoping' may be a better description. Apr 2 at 7:35
9

For completeness, if you wanted to be able to use both functions, you could switch to ksh93 (the shell bash tries to emulate anyway) where you could use namespaces.

Instead of doing:

source script2.sh

(which by the way in bash like in ksh, looks up script2.sh in $PATH which is probably not what you want), do:

namespace script2 {
  source ./script2.sh # the one in the current directory not in $PATH!
}
function execute {
  echo "Hello"
}
execute           # the one from the global namespace
.script2.execute  # the one from the script2 namespace

Note that variables also end up being namespaced.

0

You must log in to answer this question.

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