solarflare
solarflare

Reputation: 1092

Source a bash file with functions in another directory errors with 'command not found'

I have a directory similar to this:

.
|__ main
    |__ app
    |   |__ master_script.sh
    |   |__ master_parameters.sh
    |
|__ submodule
    |__ script.sh
    |__ parameters.sh
    |__ functions.sh

I want to run master_script.sh, which uses source to set a number of variables with master_parameters.sh.

master_script.sh then calls script.sh, which also uses source on parameters.sh and functions.sh. However when I do this, none of the variables in parameters.sh nor the functions in functions.sh seem to be set.

So when script.sh tries to use one of the functions, I get the error 'command not found'

i.e:

parameters.sh

my_foo="another thing"

functions.sh

functions do_task {
  echo "task done"
}

script.sh

do_task

master_parameters.sh

submodule_path=$(realpath "../../submodule")
my_foo="something"

master_script.sh

source master_parameters
cd $submodule_path
source parameters.sh
source functions.sh
./script.sh

Here when master_script.sh executes ./script.sh, it won't find the function do_task since it hasn't been correctly sourced.

From looking around there seems to be something about sourcing in different directories? I've tried to use absolute pathing but that hasn't fixed the issue. Any idea how to get around this?

Upvotes: 1

Views: 1264

Answers (3)

Antonio Petricca
Antonio Petricca

Reputation: 11026

In such cases I suggest you to translate the relative path to semi-absolute path by the following approach:

script_abs_path=$(readlink -f $(dirname $0))
source ${script_abs_path}/submodule/script.sh

Upvotes: 0

Dheisom Gomes
Dheisom Gomes

Reputation: 51

You are using ./script.sh to call the script you want to use the imported functions but that doesn't work, when we call it with ./script.sh it creates a new bash session that doesn't contain the imported functions, to fix this just use source script.sh or . script.sh, this way it will use the same shell session and keep the functions and variables imported from the other files.

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 140990

Facts:

  • Variables are not exported by default.
    • Can be exported with export.
  • Functions are not exported by default.
    • Can be exported in Bash to Bash with export -f.
  • Child process inherits exported environment (simplification).

how to get around this?

Export the function. export -f do_task before running ./script.sh.

Source the ./script.sh, so it inherits the whole current execution environment. To not affect current shell, run it in a subshell. ( source ./script.sh ).


Note that source file searches for the file in PATH. Use source ./file to source from current working directory, the same way running ./prog differs from running prog on command line.

Subjectively, prefer do_task() { over function do_task {, unlesss you really want to be compatible with ksh.

Upvotes: 2

Related Questions