ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Is there an easy way to tell, from within a bash script, if that script is being executed as part of a source command as opposed to being executed directly? I have a script that I'd like to have provide a set of functions if sourced, but actually call one of its functions if run directly.
I've gotten used to doing this sort of thing with the Python __name__ == "__main__" and Ruby __FILE__ == $0 idioms, and started writing this script accordingly before realizing I didn't even know if that made sense. (And of course, googling with "source" in the search term really doesn't give me what I'm looking for )
If I understand sourcing correctly, the code to be sourced is simply "pasted" into the host script before running. It's hard to see how the sourced code could know this was happening.
I am not a programmer, but my guess is that you want to call things like this as subroutines so you can pass arguments.
0
Expands to the name of the shell or shell script. This is set at shell initialization. If Bash is invoked with a file of commands (see Shell Scripts), $0 is set to the name of that file. If Bash is started with the -c option (see Invoking Bash), then $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the filename used to invoke Bash, as given by argument zero.
If a function is sourced and not called, where does one find the relevant value for $0?
OK, thanks burschik. Its behavior is a little complicated, but it looks like it can work.
Quote:
Originally Posted by pixellany
If a function is sourced and not called, where does one find the relevant value for $0?
Apparently from the environment it is being "sourced into". I tried out a few situations (thanks, Jan, for the examples)... From the shell itself, I get "-bash". If I source a file that echos $0, it also says "-bash". If I execute that file using bash (either with the shebang or with "bash filename" (the two should be the same, right?)) it gets set to the filename. All of that seems to match the behavior you quoted from the manual, which makes sense to me.
So, if I understand right, the value of $0 will "cascade" through sourced files, and will always show the most recent file that was executed with bash. If there isn't one, it will stay at "-bash". It looks like the only tricky part is figuring out if your particular file is being executed or sourced, as opposed to any file having been executed in the "chain". (Jan's example deals with this by checking against the expected file name.)
You could also check the BASH_SOURCE array (only bash >= 3):
Code:
$ ./s
$0 is ./s
$BASH_SOURCE is ./s
$ . s
$0 is bash
$BASH_SOURCE is ./s
$ cat s
#! /bin/bash
printf '$0 is %s\n$BASH_SOURCE is %s\n' "$0" "$BASH_SOURCE"
Something like this (I don't know if it will cover all the cases that you are interested in):
Code:
$ cat s
#! /bin/bash
[[ $BASH_SOURCE != $0 ]] && printf '%s running sourced ...\n' "$BASH_SOURCE"
$ bash s
$ ./s
$ . s
./s running sourced ...
$ source s
./s running sourced ...
I ran into this problem myself recently. I realized the simplest way to determine if a script was sourced, was to pass it a parameter telling it that it was sourced. I have verified that the snippets below do work.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.