Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

bash

In Bash, I would like to be able to both source a script and execute the file. What is Bash's equivalent to Python's if __name__ == '__main__'?

I didn't find a readily available question/solution about this topic on Stackoverflow (I suspect I am asking in such a way that doesn't match an existing question/answer, but this is the most obvious way I can think to phrase the question because of my Python experience).


p.s. regarding the possible duplicate question (if I had more time, I would have written a shorter response):

The linked to question asks "How to detect if a script is being sourced" but this question asks "how do you create a bash script that can be both sourced AND run as a script?". The answer to this question may use some aspects of the previous question but has additional requirements/questions as follows:

  • Once you detect the script is being sourced what is the best way to not run the script (and avoid unintended side-effects (other than importing the functions of interest) like adding/removing/modifying the environment/variables)
  • Once you detect the script is being run instead of sourced what is the canonical way of implementing your script (put it in a function? or maybe just put it after the if statement? if you put it after the if statement will it have side-affects?
  • most google searches I found on Bash do not cover this topic (a bash script that can be both sourced and executed) what is the canonical way to implement this? is the topic not covered because it is discouraged or bad to do? are there gotchas?
like image 821
Trevor Boyd Smith Avatar asked Apr 30 '15 11:04

Trevor Boyd Smith


People also ask

What is if name == Main in Python?

Python files can act as either reusable modules, or as standalone programs. if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported.

What is __ name __ in Python?

The __name__ variable (two underscores before and after) is a special Python variable. It gets its value depending on how we execute the containing script. Sometimes you write a script with functions that might be useful in other scripts as well. In Python, you can import that script as a module in another script.

What is bash for Python?

The Bourne-Again SHell (source code), almost always referred to simply as "Bash", interprets and executes input entered from a source such as the user or a program. Bash is an implementation of the shell concept and is often used during Python software development as part of a programmer's development environment.

How similar is bash to Python?

Python is a programming language mostly used in automation programming. Bash is a command-line interpreter or user shell to interpret user commands. Python is developed as an easy to implement an object-oriented programming language. Bash shell was introduced as a replacement of Bourne Shell.


3 Answers

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    
like image 116
Trevor Boyd Smith Avatar answered Oct 17 '22 17:10

Trevor Boyd Smith


return 2> /dev/null

For an idiomatic Bash way to do this, you can use return like so:

_main(){
    echo hello
}

# End sourced section
return 2> /dev/null

_main

Example run:

$ bash return_test.sh 
hello
$ source return_test.sh 
$ _main
hello

If the script is sourced, return will return to the parent (of course), but if the script is executed, return will produce an error which gets hidden, and the script will continue execution.

I have tested this on GNU Bash 4.2 to 5.0, and it's my preferred solution.

Warning: This doesn't work in most other shells.

This is based on part of mr.spuratic's answer on How to detect if a script is being sourced.

like image 31
wjandrea Avatar answered Oct 17 '22 17:10

wjandrea


There is none. I usually use this:

#!/bin/bash

main()
{
    # validate parameters

    echo "In main: $@"

    # your code here
}

main "$@"

If you'd like to know whether this script is being source'd, just wrap your main call in

if [[ "$_" != "$0" ]]; then
    echo "Script is being sourced, not calling main()" 
else
    echo "Script is a subshell, calling main()"
    main "$@"
fi

Reference: How to detect if a script is being sourced

like image 9
dekkard Avatar answered Oct 17 '22 19:10

dekkard