What is the bash equivalent to Python's `if __name__ == '__main__'`?

Solution:

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi

I added this answer because I wanted an answer that was written in a style to mimic Python's if __name__ == '__main__' but in Bash.

Regarding the usage of BASH_SOURCE vs $_. I use BASH_SOURCE because it appears to be more robust than $_ (link1, link2).


Here is an example that I tested/verified with two Bash scripts.

script1.sh with xyz() function:

#!/bin/bash

xyz() {
    echo "Entering script1's xyz()"
}

main() {
    xyz
    echo "Entering script1's main()"
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi

script2.sh that tries to call function xyz():

#!/bin/bash

source script1.sh

xyz    

Use FUNCNAME

Method 1: Test FUNCNAME[0] (Bash 4.3+)

#!/bin/bash

_main(){
    echo hello
}

if [[ ${FUNCNAME[0]} == "main" ]]; then
    _main
fi

Example run:

$ bash funcname_test.sh 
hello
$ source funcname_test.sh 
$ _main
hello

I'm not sure how I stumbled across this. man bash doesn't describe its functionality very well, but here's what it actually does:

  • Executed script: ${FUNCNAME[0]} is main
  • Sourced script: ${FUNCNAME[0]} is source
  • Shell function: ${FUNCNAME[0]} is the function's name

Method 2: test FUNCNAME[1] inside a function (Bash 4.2)

In Bash 4.2, FUNCNAME is only available within a function, where FUNCNAME[0] is the name of the function, and FUNCNAME[1] is the name of the caller. So for a top-level function, FUNCNAME[1] will be main in an executed script, or source in a sourced script.

This example should work just like the example above.

#!/bin/bash

get_funcname_1(){
    printf '%s\n' "${FUNCNAME[1]}"
}

_main(){
    echo hello
}

if [[ $(get_funcname_1) == main ]]; then
    _main
fi