5

In Python, the common idiom is to write code like this:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def main():
    pass

if __name__ == "__main__":
    main()

This is done so that if a Python script is imported rather than executed, its main method won't run.

Is there a similar idiom in Bash?

Grzegorz Górkiewicz
  • 4,496
  • 4
  • 22
  • 38
Naftuli Kay
  • 87,710
  • 93
  • 269
  • 411

2 Answers2

7

You can use this snippet at top of your script to determine if script is being sourced in:

#!/bin/bash

if [[ ${BASH_SOURCE[0]} != $0 ]]; then
   printf "script '%s' is sourced in\n" "${BASH_SOURCE[0]}"
fi

When script is sourced then $0 becomes -bash, which holds otherwise the name of the script itself.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 2
    `++` for demonstrating how to use in a script, haven't had to chance to use it myself, just knew it existed. – Inian Jan 24 '17 at 20:17
4

There is a special bash variable meant for this,

BASH_SOURCE

An array variable whose members are the source filenames where the corresponding shell function names in the FUNCNAME array variable are defined. The shell function ${FUNCNAME[$i]} is defined in the file ${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}

It is literally an array variable, that holds a stack trace of sources, where ${BASH_SOURCE[0]} is the latest one.

An example shamelessly stolen from this-site, just for demonstration purposes,

Script aaa.sh

#!/bin/bash
echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}"
source bbb.sh

Script bbb.sh

#!/bin/bash
echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}"
source ccc.sh

Script ccc.sh

#!/bin/bash
echo "from ${BASH_SOURCE[0]} : BASH_SOURCE = ${BASH_SOURCE[*]}"
for i in ${BASH_SOURCE[@]}; do
    readlink -f $i
done

Running aaa.sh produces,

from aaa.sh : BASH_SOURCE = aaa.sh                
from bbb.sh : BASH_SOURCE = bbb.sh aaa.sh
from ccc.sh : BASH_SOURCE = ccc.sh bbb.sh aaa.sh
/tmp/ccc.sh                                       # -> first element showing the latest script sourced 
/tmp/bbb.sh
/tmp/aaa.sh
Community
  • 1
  • 1
Inian
  • 80,270
  • 14
  • 142
  • 161
  • So if I determine that my file is the first entry in this array, my file has been sourced? If it's not the first entry in there, it hasn't been sourced and is just executing? – Naftuli Kay Jan 24 '17 at 20:09
  • Yes, it contains the most recent script sourced. It is an atomic operation, once the file is sourced it occupies at the index at `0` – Inian Jan 24 '17 at 20:13
  • @NaftuliKay: Or refer my update for a example usage. – Inian Jan 24 '17 at 20:25