5

How do you determine if a file is being sourced from bash?

This is very similar to this question, however, none of the presented solutions work. For example, given the sourced file setup.bash:

if [ "$_" == "$0" ]
then
    echo "Please source this script. Do not execute."
    exit 1
fi

If you were to source this with: /bin/bash -c ". ./setup.bash;" you'll see the message printed "Please source this script. Do not execute.".

Why is this?

I'm sourcing the file this way because my end goal is to execute a bash script that relies on this sourced file, meaning I eventually want to do:

`/bin/bash -c ". ./setup.bash; some_command_that_relies_on_setup_dot_bash;"`

If I run these in bash directly, like:

. ./setup.bash
some_command_that_relies_on_setup_dot_bash

the sourced file doesn't display the message. What am I doing wrong?

Community
  • 1
  • 1
Cerin
  • 60,957
  • 96
  • 316
  • 522

2 Answers2

5

Using $_ can be error prone as it represents arguments from last executed command only.

It is better to check BASH_SOURCE instead like this:

if [[ "$0" = "$BASH_SOURCE" ]]; then
    echo "Please source this script. Do not execute."
fi

BASH_SOURCE variable always represents name of the script being executed i.e. ./setup.sh irrespective of the fact whether you are sourcing it in or not.

On the other hand $0 can be name of script when you directly execute it or be equal to -bash when you source it in.

Jay Taylor
  • 13,185
  • 11
  • 60
  • 85
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

When I run your example, with just the code you posted, I cannot reproduce the issue.

But: Make sure you won't execute any commands before that check (or backup ${_} in a variable) since:

_($_, an underscore.) At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname used to invoke each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266