2

I have a bash file, src-useful.bash, containing useful functions such as say_hello(),located in /path/to/useful.

In my ~/.bash_profile I added the following lines:

export BASH_USEFUL=/path/to/useful
source $BASH_USEFUL/src-useful.bash

Opening a new terminal I can check the following:

$ echo $BASH_USEFUL
/path/to/useful

$ cat $BASH_USEFUL/src-useful.bash
function hello() {
    echo "hello!"
}

$ hello
hello!

I created a script, say_hello.sh:

$ cat say_hello.sh
echo "BASH_USEFUL: $BASH_USEFUL"
hello

$ ./say_hello.sh
BASH_USEFUL: /path/to/useful  # Recognizsed
say_hello.sh: line 2: say_hello: command not found  # Not recognized?

If I source $BASH_USEFUL/src-useful.bash in say_hello.sh it will work however:

$ cat say_hello.sh
echo "BASH_USEFUL: $BASH_USEFUL"
source $BASH_USEFUL/src-useful
say_hello

$ ./say_hello.sh
BASH_USEFUL: /path/to/useful  # Recognized
hello!  # Function say_hello is now recognized

I would like to know why the variable BASH_USEFUL is still recognized by my script, while the functions from my sourced file cannot be seen in the environment by my running script. Is there a workaround apart from sourcing my src-useful.bash in my scripts? I would like src-useful.bash's functions to be loaded in the environment of any script I launch.

  • Seems you changed the call to the sourced function hello() to say_hello() in the steps above... – venzen Jul 12 '16 at 14:33
  • Ah yes thanks I corrected it. The problem is still here though – kaligne Jul 12 '16 at 14:53
  • That's...a horrible way to write programs. It'll bite you sooner or later. – grawity Jul 13 '16 at 4:37
  • Thanks grawity, how should I source my generic functions then? – kaligne Jul 13 '16 at 7:06
3

Only exported environment items are copied to new child environments. You exported BASH_USEFUL so this env-var is copied to your ./say_hello.sh sub process as expected. But you did not do the same for your function hello() which is then a simple local symbol not to be copied in new child environments.

Syntax to export functions using bash uses the -f argument of export:

export -f hello
  • So that means I sould either manually export all the functions (yuk) or source the file in all my scripts? – kaligne Jul 13 '16 at 7:07
  • Yes. But exporting all functions can be quite easy if you think about that when you write your scripts. You can either: 1) add a export -f after each function body, or 2) add a MYSCRIPT_FUNCS="${MYSCRIPT_FUNCS} foo" after each function body with an extra helper function myscript_export_all() which calls export -f on all tokens of this variable for example. And import this script using a syntax like source myscript.sh && myscript_export_all. – A. Loiseau Jul 16 '16 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.