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.

Either what I'm asking here is extremely unorthodox/unconventional/risky, or my Google-fu skills just aren't up to snuff...

In a bash shell script, is there any easy of way of telling if it is getting sourced by another shell script, or is it being run by itself? In other words, is it possible to differentiate between the following two behaviors?

# from another shell script
source myScript.sh

# from command prompt, or another shell script
./myScript.sh

What I'm thinking of doing is to create an utilities-like shell script containing bash functions that can be made available when sourced. When this script is being run by itself though, I'll like it to perform certain operations, based on the defined functions too. Is there some kind of an environment variable that this shell script can pick up on, e.g.

some_function() {
    # ...
}
if [ -z "$IS_SOURCED" ]; then
    some_function;
fi

Preferably, I'm looking for a solution that doesn't require the caller script to set any flag variables.

edit: I know the difference between sourcing and and running the script, what I'm trying to find out here if it's possible to tell the difference in the script that is being used (in both ways).

share|improve this question
1  
possible duplicate of running script with ". " and with "source " –  cuonglm 21 hours ago
    
@cuonglm edited my question, I know the differences between the both but I'm wondering if I can programmatically make the shell script tell the difference as well. –  h.j.k. 21 hours ago
2  
@cuonglm: Not a duplicate. He's not asking about the . command at all, but about detecting whether a script has been sourced or run normally (i.e. in a subshell). –  Jander 17 hours ago

2 Answers 2

up vote 13 down vote accepted

Yes - the $0 variable gives the name of the script as it was run:

$ cat example.sh
#!/bin/bash
script_name=$( basename $0 )
this_script=$( basename ${BASH_SOURCE} )
if [[ ${script_name} = ${this_script} ]] ; then
    echo "running me directly"
else
    echo "sourced from ${script_name}"
fi 

$ cat example2.sh
#!/bin/bash
. ./example.sh

Which runs like:

$ ./example.sh
running me directly
$ ./example2.sh
example.sh sourced from example2.sh

That doesn't cater for being source from an interactive shell, but you get this idea (I hope).

Updated to include BASH_SOURCE - thanks h.j.k

share|improve this answer
    
Close enough. :) Small hindrance that I'll need to specify the script's name at least, but I'll take this answer if there are no other viable solutions... –  h.j.k. 21 hours ago

Combining @DarkHeart's answer with the environment variable BASH_SOURCE seems to do the trick:

$ head example*.sh
==> example2.sh <==
#!/bin/bash
. ./example.sh

==> example.sh <==
#!/bin/bash
[ "$(basename $0)" = "$(basename $BASH_SOURCE)" ] && \
    echo "running directly" || \
    echo "sourced from $0"
$ ./example2.sh
sourced from ./example2.sh
$ ./example.sh
running directly

edit Seems to be a simpler solution still if I were to just count the number of elements in BASH_SOURCE's array:

[ ${#BASH_SOURCE[@]} -eq 1 ] && echo "running directly" || echo "sourced from $0"
share|improve this answer
1  
Looks like we found the 'bash_source' variable at the same time. :) –  DarkHeart 20 hours ago
    
@DarkHeart I've added onto my answer the usage of counting the array size too... thanks for hinting me on this path! :D –  h.j.k. 20 hours ago
    
+1 That's clever. –  DarkHeart 20 hours ago

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.