10

I want to how to determine if a script file is executed or sourced.

For example,

# Shell script filename build.sh
if [ "x$0" = "xbash" ]; then
    echo "I am sourced by Bash"
else
    echo "I am executed by Bash"
fi

If I typed

source build.sh

it would output I am sourced by Bash.

If I typed

./build.sh

it would output I am executed by Bash.

Currently, I use $0 to do this. Is there a better idea?

Inspired by Tripeee, I found a better way:

#!/bin/bash

if [ "x$(awk -F/ '{print $NF}' <<< $0)" = 'xcdruntime' ]; then
    echo Try to source me, not execute me.
else
    cd /opt/www/app/pepsi/protected/runtime
fi
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hellojinjie
  • 1,868
  • 3
  • 17
  • 23

1 Answers1

10

It doesn't work if sourced by another script. I would go the other way around;

test "X$(basename -- "$0")" = "Xbuild.sh" || echo Being sourced

Update: added X prefix to both strings.

Update too: added double dash to basename invocation.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Yeh, Your sulution is better than mine. If the script is sourced by another script, $0 will not be `bash` – hellojinjie Mar 24 '12 at 10:54
  • I have to say that your solution is not the best one, it works fine on ubuntu, but it failed on Enterprise Linux 5. On ubuntu, when source a script file, $0 is `bash`, whereas on EL5, the $0 is `-bash`. when basename met -bash, an error occur – hellojinjie Mar 24 '12 at 11:51
  • 1
    Ooops, you're right. Updated my answer. Thanks for your feedback. – tripleee Mar 24 '12 at 16:38
  • $(basename -bash) will raise an error. I replace basename with awk. see my update in my question. thank you – hellojinjie Mar 26 '12 at 07:06
  • 1
    Actually you can use `$(basename -- "$0")` to work around that. The double dash is undocumented in my version of `basename` but a widely supported convention. – tripleee Mar 26 '12 at 11:02
  • after reading the source of basename.c and googleing, I find the double dash is documented here [Get-Opt](http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt) (: By saying `The double dash is undocumented in my version of basename`, did you mean that you are the author of basename? – hellojinjie Mar 28 '12 at 07:49
  • No, I mean in the `coreutils` package I have installed on my workstation. – tripleee Mar 28 '12 at 13:11
  • 1
    You don't need to prefix the strings with "X". As long as you quote them both, `test` will correctly handle any string you throw at it, whether it's empty or starts with a dash. – Søren Løvborg Feb 09 '14 at 19:15
  • 1
    Reasonably modern versions of `test` cope with values which start with a dash, but this wasn't always true. – tripleee Feb 10 '14 at 05:36