0

I have a script, which has a lot of functions inside.

myfile1.sh:

func1() {}

func2() {}

I can call them from script with:

myfile2.sh:

source myfile1.sh

func1

func2

But how can I call them if sourced in nested script?

myfile3.sh:

./myfile2.sh

func2

func2: command not found

Can I "export" functions from myfile2 so that everybody knew them?

I can't use export -f because there are many functions.

  • 1
    I'm assuming that running myfile3.sh recursively is a typo? You also know that there is no way to export anything to a parent or sibling process? – Kusalananda Jun 7 at 8:19
  • I can export variables, can't I? – Dims Jun 7 at 8:29
  • @Dims not to a parent shell. – muru Jun 7 at 8:33
  • @muru then how can I set variables in bashrc or any other scripts? They should be confined inside them. – Dims Jun 7 at 8:35
  • 2
    @Dims Not everything you run is a script written for your particular shell, so you can't source everything all the time. For example, the mktemp utility is not a script that you can source, yet it examines its environment for the value of the TMPDIR variable. If that variable wasn't exported, you would have to use other means to create temporary files in a specific directory (just as an example). – Kusalananda Jun 7 at 8:49
3

Note that bash is not sh. export -f is specific to the bash shell.

If a script doesn't have a she-bang, it will be interpreted by a POSIX-like shell which may not be bash. If you intend to use bash-specific features in your script, you should make sure it has a:

#! /path/to/bash -

she-bang or that you invoke it as bash path/to/the/script. Also giving .sh extensions to scripts written in the bash language is a bit misleading.

Now bash is one of those few shells which are able to export functions to the environment (in effect using special environment variables understood by bash commands only). It can be done using the export -f bash-specific command. bash also exports all functions that are declared whilst the allexport option is on.

But in any case, neither of those would work in your case. exporting something from one shell, whether it's a variable or function, is so that that variable/function is available in other shells that that shell executes (exporting is about preserving things across execution).

So even if the myfile1.sh or myfile2.sh exported the functions they declared (with export -f or by having a set -o allexport before the variable declaration), that would only affect the shells that the shell interpreting those scripts would execute. Here myfile2.sh is not executing myfile3.sh, it's the other way round.

Here you'd need your myfile3.sh script to do:

source path/to/myfile2.sh

so that it's the same shell that interprets the code in all of the myfile1.sh, myfile2.sh and myfile3.sh scripts, and then you wouldn't need to export any function.

Note that on systems where sh is bash, it's probably not a good idea to export functions, as that affects all sh and bash scripts and shell command lines that your script executes (recursively). For instance, if you did:

set -o allexport
uname() { echo Gotcha; }
somecmd

And somecmd was doing a popen("uname", "r") to get the unix name, it would get Gotcha on systems where sh is bash instead of the real name of the system (Darwin, Linux...).

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.