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:
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.
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.
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.
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.
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
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With