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.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have defined a bash function in my ~/.bashrc file. This allows me to use it in shell terminals. However, it does not seem to exist when I call it from within a script.

How can I define a bash function to be used by scripts as well?

share|improve this question
But my .bash_profile basically reads the .basrc file, so I would expect the result to be the same regardless I use login or non-login shell. – Onturenio Feb 4 '13 at 16:17
Are you using /bin/sh in the shebang line? – Kevin Feb 4 '13 at 16:21
up vote 5 down vote accepted

~/.bash_profile and ~/.bashrc are not read by scripts, and functions are not exported by default. To do so, you can use export -f like so:

$ cat > script << 'EOF'
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; } 
$ export -f foo
$ ./script

export -f foo could also be called in ~/.bash_profile to make this function available to scripts after login. Be warned that export -f is not portable.

A better solution would be to source the file containing the function using . file. This is much more portable, and doesn't rely on your environment being set up in a particular way.

share|improve this answer
why not just declare a function like function myFunction { ... } in ~/.bash_profile and you're good to go? – amphibient Feb 4 '13 at 16:34
If I understood properly your answer (regarding sourcing a file with the function), this would mean that I have to source the file explicitly in every script, which is pretty much annoying. This is not much less complicated than just copy-pasting the function itself in every script. I would save some lines, sure, but that's all. However, the export solution seems to work properly. Thanks. – Onturenio Feb 4 '13 at 16:53
@foampile, this is precisely what I did and does not work when calling the function from a script. – Onturenio Feb 4 '13 at 16:56
@Onturenio : the second method @chris-down proposed is indeed better: 1) When someone read the script, they are aware that it needs some foo function from some file 2) You can better control the content of that file than make sure that the invoking shell didn't change foo before invoking your script. You could add safety checks on file to make sure it's untampered, for example. (not easy, but possible). (well, you could also do those checks on the defined foo function... but you get my drift ^^ I think the method 2 is cleaner.) 3) file will only contain what's needed, not more. – Olivier Dulac Feb 4 '13 at 17:25

.bashrc is only read by interactive shells. (Actually, that's an oversimplification: bash is quirky in this respect. Bash doesn't read .bashrc if it's a login shell, interactive or not. And there's an exception even to the exception: if bash's parent process is rshd or sshd, then bash does read .bashrc, whether it's interactive or not.)

Put your function definitions in a file in a known place, and use the . (also spelled source) builtin to include that file in a script.

$ cat ~/lib/bash/my_functions.bash
foo () {
$ cat ~/bin/myscript
. ~/lib/bash/my_functions.bash
foo bar

If you want, you can follow ksh's autoload feature. Put each function definition in a file with the same name as the function. List the directories containing the function definitions in the FPATH variable (a colon-separated list of directories). Here's a crude approximation of ksh's autoload which actually loads the function immediately instead of on-demand:

autoload () {
  set -- "$(set +f; IFS=:;
            for d in $FPATH; do
              if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
  [[ -n $1 ]] && . "$1"
share|improve this answer
+1 for autoload, although I recommend using the ones that come with bash. The latest one supports lazy load. – Starfish Jan 29 '15 at 5:30

Do you need a function? If not, consider pulling out the logic into a separate, stand-alone Bash script in your $PATH. For example, I had this in my ~/.bashrc:

# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

~/bin is in my $PATH, so I created ~/bin/wanip with the following contents:


# echo public IP address
dig +short myip.opendns.com @resolver1.opendns.com

And ran chmod 0755 ~/bin/wanip to make it executable. Now I can execute wanip from other scripts.

I like having wanip in a stand-alone Bash script. It reminds me that I want this logic generally available (besides just in my current interactive Bash session). The script nicely encapsulates the logic and documentation for same.

share|improve this answer

Your Answer


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.