What are the functional differences between .profile .bash_profile and .bashrc
What are the functional differences between the .profile
, .bash_profile
and .bashrc
files?
.bash_profile
and .bashrc
are specific to bash
, whereas .profile
is read by many shells in the absence of their own shell-specific config files. (.profile
was used by the original Bourne shell.) .bash_profile
or .profile
is read by login shells, along with .bashrc
; subshells read only .bashrc
. (Between job control and modern windowing systems, .bashrc
by itself doesn't get used much. If you use screen
or tmux
, screens/windows usually run subshells instead of login shells.)
The idea behind this was that one-time setup was done by .profile
(or shell-specific version thereof), and per-shell stuff by .bashrc
. For example, you generally only want to load environment variables once per session instead of getting them whacked any time you launch a subshell within a session, whereas you always want your aliases (which aren't propagated automatically like environment variables are).
Other notable shell config files:
/etc/bash_profile
(fallback /etc/profile
) is read before the user's .profile
for system-wide configuration, and likewise /etc/bashrc
in subshells (no fallback for this one). Many systems including Ubuntu also use an /etc/profile.d
directory containing shell scriptlets, which are .
(source
)-ed from /etc/profile
; the fragments here are per-shell, with *.sh
applying to all Bourne/POSIX compatible shells and other extensions applying to that particular shell.
.profile
.profile
is for things that are not specifically related to Bash
, like environment variables PATH
and friends, and should be available anytime.
For example, .profile
should also be loaded when starting a graphical desktop session.
.bashrc
.bashrc
is for the configuring the interactive Bash usage, like Bash aliases
, setting your favorite editor
, setting the Bash prompt
, etc.
.bash_profile
.bash_profile is for making sure that both the things in .profile
and .bashrc
are loaded for login shells
.
For example, .bash_profile
could be something simple like
. ~/.profile
. ~/.bashrc
If you were to omit .bashrc
, only .profile
would be loaded.
According to the bash man page, .bash_profile
is executed for login shells, while .bashrc
is executed for interactive non-login shells.
So, what is a login or non-login shell?
When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile
is executed to configure your shell before the initial command prompt.
But, if you’ve already logged into your machine and open a new terminal window (xterm) inside Gnome or KDE, then .bashrc
is executed before the window command prompt. .bashrc
is also run when you start a new bash instance by typing /bin/bash
in a terminal.
An exception to the terminal window guidelines is Mac OS X’s Terminal.app, which runs a login shell by default for each new terminal window, calling .bash_profile
instead of .bashrc
. Other GUI terminal emulators may do the same, but most tend not to.
More at: .bash_profile vs .bashrc - by Josh Staiger.
I resorted to the man page for this answer (man bash
).
The three files are all used by bash in different scenarios.
Scenario 1: interactive login shell (interactive means you can do user input. Note this does NOT include cron jobs! A login shell is the first shell that is spawned when you login, but does not include sub-shells) So basically this is the command prompt you get right when you login. What will bash do? Bash reads /etc/profile every time. Then, it looks for ~/.bash_profile. If it doesn't exist, it looks for ~/.bash_login. If that doesn't exist, then it looks for ~/.profile. But it will only read one of .bash_profile, .bash_login, and .profile. So it will quit after it finds one and reads it.
Scenario 2: interactive non-login (This is a shell that is started after the first login shell. This shell is one that allows user input). When an interactive non-login shell is started: Bash just reads /etc/bash.bashrc and ~/.bashrc.
Scenario 3: non-interactive shell (for example cronjob) When non-interactive, it doesn't load any of the files at all. But, it does look for an environment variable called BASH_ENV which is supposed to contain the path to a file that will be executed. So in this case, it doesn't read any of the ~/.profile or ~/.bash_profile files unless you explicitly set the BASH_ENV to an absolute path. I believe this is why you should always specify the absolute path in any cronjobs because none of the config files get executed by default.
Here is my source
From bash(1) - Linux man page