About .bash_profile, .bashrc, and where should alias be written in?
The reason you separate the login and non-login shell is because the .bashrc
file is reloaded every time you start a new copy of Bash. The .profile
file is loaded only when you either log in or use the appropriate flag to tell Bash to act as a login shell.
Personally,
- I put my
PATH
setup into a.profile
file (because I sometimes use other shells); - I put my Bash aliases and functions into my
.bashrc
file; I put this
#!/bin/bash # # CRM .bash_profile Time-stamp: "2008-12-07 19:42" # # echo "Loading ${HOME}/.bash_profile" source ~/.profile # get my PATH setup source ~/.bashrc # get my Bash aliases
in my
.bash_profile
file.
Oh, and the reason you need to type bash
again to get the new alias is that Bash loads your .bashrc
file when it starts but it doesn't reload it unless you tell it to. You can reload the .bashrc
file (and not need a second shell) by typing
source ~/.bashrc
which loads the .bashrc
file as if you had typed the commands directly to Bash.
Check out http://mywiki.wooledge.org/DotFiles for an excellent resource on the topic aside from man bash
.
Summary:
- You only log in once, and that's when
~/.bash_profile
or~/.profile
is read and executed. Since everything you run from your login shell inherits the login shell's environment, you should put all your environment variables in there. LikeLESS
,PATH
,MANPATH
,LC_*
, ... For an example, see: My.profile
- Once you log in, you can run several more shells. Imagine logging in, running X, and in X starting a few terminals with bash shells. That means your login shell started X, which inherited your login shell's environment variables, which started your terminals, which started your non-login bash shells. Your environment variables were passed along in the whole chain, so your non-login shells don't need to load them anymore. Non-login shells only execute
~/.bashrc
, not/.profile
or~/.bash_profile
, for this exact reason, so in there define everything that only applies to bash. That's functions, aliases, bash-only variables like HISTSIZE (this is not an environment variable, don't export it!), shell options withset
andshopt
, etc. For an example, see: My.bashrc
- Now, as part of UNIX peculiarity, a login-shell does NOT execute
~/.bashrc
but only~/.profile
or~/.bash_profile
, so you should source that one manually from the latter. You'll see me do that in my~/.profile
too:source ~/.bashrc
.
From the bash manpage:
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
.
Thus, if you want to get the same behavior for both login shells and interactive non-login shells, you should put all of your commands in either .bashrc
or .bash_profile
, and then have the other file source the first one.