Why no shebang in .bashrc/.bash_profile?
Solution 1
.bashrc
and .bash_profile
are NOT scripts. They're configuration file which get sourced every time bash
is executed in one of 2 ways:
- interactive
- login
The INVOCATION section of the bash man page is what's relevent.
A login shell is one whose first character of argument zero is a
-
, or one started with the--login
option.An interactive shell is one started without non-option arguments and without the
-c
option whose standard input and error are both connected to terminals (as determined byisatty(3))
, or one started with the-i
option. PS1 is set and$-
includesi
ifbash
is interactive, allowing a shell script or a startup file to test this state.The following paragraphs describe how
bash
executes its startup files. If any of the files exist but cannot be read, bash reports an error. Tildes are expanded in file names as described below under Tilde Expansion in the EXPANSION section.When bash is invoked as an interactive login shell, or as a non-interactive shell with the
--login
option, it first reads and executes commands from the file/etc/profile
, if that file exists. After reading that file, it looks for~/.bash_profile
,~/.bash_login
, and~/.profile
, in that order, and reads and executes commands from the first one that exists and is readable. The--noprofile
option may be used when the shell is started to inhibit this behavior.When a login shell exits, bash reads and executes commands from the file
~/.bash_logout
, if it exists.When an interactive shell that is not a login shell is started, bash reads and executes commands from
~/.bashrc
, if that file exists. This may be inhibited by using the--norc
option. The--rcfile file
option will force bash to read and execute commands from file instead of~/.bashrc
.
You can control when they get loaded through the command line switches, --norc
and --noprofile
. You can also override the location of where they get loaded from using the --rcfile
switch.
As other's have mentioned you can mimic how these files get loaded through the use of the source <file>
command or the use of the . <file>
command.
It's best to think of this functionality as follows:
- bash starts up with a bare environment
- bash then opens one of these files (depending on how it was invoked as interactive or login, and then...
- ...line by line executes each of the commands within the file...
- when complete gives control to in the form of a prompt, waiting for input
Methods for invoking
This topic seems to come up every once in a while, so here's a little cheatsheet of the various ways to invoke bash
and what they result in. NOTE: To help I've added the messages "sourced $HOME/.bashrc" and "sourced $HOME/.bash_profile" to their respective files.
basic calls
-
bash -i
$ bash -i sourced /home/saml/.bashrc
-
bash -l
$ bash -l sourced /home/saml/.bashrc sourced /home/saml/.bash_profile
-
bash -il -or- bash -li
$ bash -il sourced /home/saml/.bashrc sourced /home/saml/.bash_profile
-
bash -c "..cmd.."
$ bash -c 'echo hi' hi
NOTE: Notice that the
-c
switch didn't source either file!
disabling config files from being read
-
bash --norc
$ bash --norc bash-4.1$
-
bash --noprofile
$ bash --noprofile sourced /home/saml/.bashrc
-
bash --norc -i
$ bash --norc -i bash-4.1$
-
bash --norc -l
$ bash --norc -l sourced /home/saml/.bashrc sourced /home/saml/.bash_profile
-
bash --noprofile -i
$ bash --noprofile -i sourced /home/saml/.bashrc
-
bash --noprofile -l
$ bash --noprofile -l bash-4.1$
-
bash --norc -i -or- bash --norc -l
$ bash --norc -c 'echo hi' hi
More esoteric ways to call bash
-
bash --rcfile $HOME/.bashrc
$ bash -rcfile ~/.bashrc sourced /home/saml/.bashrc
-
bash --norc --rcfile $HOME/.bashrc
$ bash --norc -rcfile ~/.bashrc bash-4.1$
These failed
-
bash -i -rcfile ~/.bashrc
$ bash -i -rcfile ~/.bashrc sourced /home/saml/.bashrc sourced /home/saml/.bash_profile bash: /home/saml/.bashrc: restricted: cannot specify `/' in command names
-
bash -i -rcfile .bashrc
$ bash -i -rcfile .bashrc sourced /home/saml/.bashrc sourced /home/saml/.bash_profile bash: .bashrc: command not found
There are probably more but you get the point, hopefully....
What else?
Lastly if you're so enthralled with this topic that you'd like to read/explore more on it, I highly suggest taking a look at the Bash Beginners Guide, specifically section: 1.2. Advantages of the Bourne Again SHell. The various subsections under that one, "1.2.2.1. Invocation" through "1.2.2.3.3. Interactive shell behavior" explain the low level differences between the various ways you can invoke bash
.
Solution 2
.bashrc
scripts are only run by bash
itself. They're not free-standing, and they're not intended to be exec
uted by the system. (In fact, they're generally not marked executable, and, as you say, they don't have a shebang line.)
Such scripts are intended to be source
d, since they generally do things like change environment variables ($PATH
, for example), which are expected to persist after the script finishes. So it would really be pointless to try to execute one in a subshell.
Solution 3
In addition to the other replies, note that if you want it, nothing forbids you to put a shebang at the beginning of these configuration files.
That wouldn't hurt shell sourcing them as the shebang will be processed just like a regular comment, i.e. ignored.
That might help editors that use syntax highlighting to figure out what programming language is used in the file.
Note that some editors like vim
provide alternative ways like modelines for the latter though. i.e. you can always put mode lines at the end of the ~/.bashrc
and ~/.bash_profile
like so:
...
<code in ~/.bashrc>
...
# vim: ft=sh :
Solution 4
I read this anywhere don't know where exactly but it's true
The Bash manual is a bit confusing in this area, but Bash does not eXecute ~/.bash_profile like a shell script. It does read the file and then executes the commands within it (You can do something similar by running source ~/.bash_profile).
Related videos on Youtube
Comments
-
amphibient over 1 year
Simple inquiry: I have just realized that I have never seen a shebang on top of a
.bashrc
script, which leads me to think the system uses the default shell to source it upon login (${SHELL}
). I am pondering over reasons why that is the case, i.e. is it considered a bad habit to use something other than the default shell to run the login script. -
slm over 10 years@amphibient - sorry it got a little out of hand, hopefully people will appreciate its value and not punish it with downvotes. With this here we can now reference it in other answer down the road. 8-). I was contemplating making a table to show this but that would've been crazy 8-).
-
Bananguin over 10 yearsHave actually tested these? I once tried to follow what my bash does in squeeze and it didnt quite behave as the manual suggested
-
slm over 10 years@Bananguin - every one of those commands was run by me and that's the output that was produced below the commands. The only potential "thing" with my setup might be that my
.bash_profile
includes a line to source the.bashrc
. But I believe that to be very typical of setups. -
Jacob Tomlinson over 9 yearsThis answer is even better than any answers here stackoverflow.com/questions/415403/…!
-
slm over 9 years@JacobTomlinson - thank you for your kind words!
-
jlucktay over 6 yearsThe accepted answer from @slm above is great, but this is what I was looking for, with regard to adding a shebang to the start of my
.bash_profile
on a recommendation from ShellCheck.