Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.
source some_file

some_file:

doit ()
{
  echo doit $1
}
export TEST=true

If I source some_file the function "doit" and the variable TEST are available on the command line. But running this script:

script.sh:

#/bin/sh
echo $TEST
doit test2

Will return the value of TEST, but will generate an error about the unknown function "doit".

Can I "export" the function, too, or do I have to source some_file in script.sh to use the function there?

share|improve this question
2  
summarizing answers below (enzotib is correct, assuming you can use bash, as the question indicates): change #!/bin/sh to #!/bin/bash and after doit() {...} just export -f doit –  michael_n Jun 11 '13 at 21:08
    
Just for the record: This solution will usually work when you use #!/bin/sh too, but it is good practice to use #!/bin/bash so that you avoid problems when the default shell is not bash. –  Nagel Aug 5 at 12:16

5 Answers 5

up vote 30 down vote accepted

In bash you can export function definitions to sub-shell with

export -f function_name

For example you can try this simple example:

./script1:

    #!/bin/bash

    myfun() {
        echo "Hello!"
    }

    export -f myfun
    ./script2

./script2:

    #!/bin/bash

    myfun

Then if you call ./script1 you will see the output Hello!.

share|improve this answer

Functions are not exported to subprocesses. This is why there are files named .kshrc or .bashrc: To define functions that shoiuld be available in subshells also.

If running a script, the .*shrc scripts are normally not sourced. You would have to code that explicitly, like in . ~/.kshrc.

share|improve this answer
    
So the ~root/.bashrc could be an option in my case, since the scripts are run as root. Thanks for that hint. –  Nils Oct 17 '11 at 19:06
    
if using the .*shrc files, be sure they dont force interactive behaviour (like the stupid alias rm=rm -i) –  ktf Oct 18 '11 at 8:50

You cannot export functions, not in the way that you are describing. The shell will only load the ~/.bashrc file on the start of an interactive shell (search for "Invocation" in the bash manpage).

What you can do is create "library" which is loaded when you start the program:

source "$HOME/lib/somefile"

And place your non-interactive functions and settings there.

share|improve this answer
    
So I have to either start the subshell with the "login" parameter (to parse ~/.profile) or source that file. –  Nils Oct 17 '11 at 19:11
    
Looking a little more closely, on non-interactive shells, you could set BASH_ENV environment variable to some_file you already have, and it would be called. It would be easy enough to find that out: echo echo foobar > /tmp/foobar; BASH_ENV=/tmp/foobar $SHELL -c : –  Arcege Oct 17 '11 at 19:20

"Exporting" a function using export -f creates an environment variable with the function body. Consider this example:

$ fn(){ echo \'\"\ \ \$; }
$ export -f fn
$ sh -c printenv\ fn
() {  echo \'\"\ \ \$
}

This means that only the shell (just Bash?) will be able to accept the function. You could also set the function yourself as the Bash only considers envvars starting with () { as function:

$ fn2='() { echo Hi;}' sh -c fn2
Hi
$ fn3='() {' sh -c :
sh: fn3: line 1: syntax error: unexpected end of file
sh: error importing function definition for `fn3'

If you need to "export" this variable over SSH, then you really need the function as a string. This can be done with the print option (-p) for functions (-f) of the declare built-in:

$ declare -pf fn
fn () 
{ 
    echo \'\"\ \ \$
}

This is very useful if you have more complex code that needs to be executed over SSH. Consider the following fictitious script:

#!/bin/bash
remote_main() {
   local dest="$HOME/destination"

   tar xzv -C "$dest"
   chgrp -R www-data "$dest"
   # Ensure that newly written files have the 'www-data' group too
   find "$dest" -type d -exec chmod g+s {} \;
}
tar cz files/ | ssh "$(declare -pf remote_main); remote_main"
share|improve this answer

well, i'm new in linux, but you can try this:

in some file, let's call it: 'tmp/general' you build your function:

func1(){
   echo "func from general"
}

in your shell script add :

. /tmp/general

and run:

func1

you'll get on the screen: "func from general"

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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