Mark
Mark

Reputation: 6394

How can I source multiple bash scripts into each others properly?

Let us say I have the following script files:

~/src/setup.sh::

#!/usr/bin/env bash

dn=$( dirname "$0" )
source "$dn/init/init.sh"

~/src/init/init.sh:

#!/usr/bin/env bash

dn=$( dirname "$0" )
source "$dn/start.sh"

start_servers "param1" "param2"

~/src/init/start.sh:

#!/usr/bin/env bash

start_servers() {
  # ...
  printf "start the servers..."
  # ...
}

Sourcing the second file (start.sh) results that:

$ ./setup.sh
./init/init.sh: line 4: ./start.sh: No such file or directory
./init/init.sh: line 6: start_servers: command not found

Since I execute the setup.sh from ., after sourcing the files, start.sh seems to be sourced from . as well but I would like to source it from its proper location.

Any idea how to fix it? Thanks in advance.

Upvotes: 4

Views: 2575

Answers (2)

Jeremy Gurr
Jeremy Gurr

Reputation: 1623

If you use sh instead of source, it will load up the environment as you expect, instead of executing the script in the same environment:

dn=$( dirname "$0" )
sh "$dn/init/init.sh"

This change will cause the code to run in a subshell instead of the same shell. You won't be able to do this for a script that needs a function from an outer shell, since you will still need to source that to have access to the function. But in your case, the only script that needs that can still be sourced, since you don't need $0 there.

Upvotes: -2

mklement0
mklement0

Reputation: 437042

Bash has the built-in $BASH_SOURCE variable, which is similar to $0, but - unlike the latter - correctly reflects the name of the running script even when sourced.

Thus, simply replacing $0 with $BASH_SOURCE in your scripts should be enough.

Upvotes: 6

Related Questions