Sunday, January 22, 2012

Execution sequence for .bash_profile, .bashrc, .bash_login, .profile and .bash_logout


This article will explain the sequence in which the following files are executed:
  • /etc/profile
  • ~/.bash_profile
  • ~/.bashrc
  • ~/.bash_login
  • ~/.profile
  • ~/.bash_logout

Execution sequence for interactive login shell

Following pseudo code explains the sequence of execution of these files.
execute /etc/profile
IF ~/.bash_profile exists THEN
    execute ~/.bash_profile
ELSE
    IF ~/.bash_login exist THEN
        execute ~/.bash_login
    ELSE
        IF ~/.profile exist THEN
            execute ~/.profile
        END IF
    END IF
END IF
When you logout of the interactive shell, following is the sequence of execution:
IF ~/.bash_logout exists THEN
    execute ~/.bash_logout
END IF
Please note that /etc/bashrc is executed by ~/.bashrc as shown below:
# cat ~/.bashrc
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

Execution sequence for interactive non-login shell

While launching a non-login interactive shell, following is the sequence of execution:
IF ~/.bashrc exists THEN
    execute ~/.bashrc
END IF
Note: When a non-interactive shell starts up, it looks for ENV environment variable, and execute the file-name value mentioned in the ENV variable.

Test the sequence of execution

One of the ways to test the sequence of execution is by adding different PS1 values to these files and re-login to the shell and see which PS1 value got picked up by the Linux prompt. Also, earlier we discussed about how to use PS1 to make your Linux prompt both functional and stylish.

1. /etc/profile gets executed. Add following PS1 line to /etc/profile and re-login to make sure the Linux prompt changes to the PS1 value set inside the /etc/profile.
# grep PS1 /etc/profile
PS1="/etc/profile> "

[Note: re-login to see the prompt change as shown below]
Last login: Sat Sep 27 16:43:57 2008 from 192.168.1.2
/etc/profile>
Please make sure ~/.bash_profile doesn’t have any PS1 for the above to work properly.
2. ~/.bash_profile gets executed: Add following PS1 to ~/.bash_profile, ~/.bash_login, ~/.profile and ~/.bashrc. Re-login to make sure the Linux prompt changes to the PS1 value set inside the  ~/.bash_profile as shown below.
/etc/profile> grep PS1 ~/.bash_profile
export PS1="~/.bash_profile> "

/etc/profile> grep PS1 ~/.bash_login
export PS1="~/.bash_login> "

/etc/profile> grep PS1 ~/.profile
export PS1="~/.profile> "

/etc/profile> grep PS1 ~/.bashrc
export PS1="~/.bashrc> "

[Note: Upon re-login, it executed /etc/profile first and ~/.bash_profile next.
So, it took the PS1 from ~/.bash_profile as shown below.
It also did not execute ~/.bash_login, as ~/.bash_profile exists]
Last login: Sat Sep 27 16:48:11 2008 from 192.168.1.2
~/.bash_profile>
3. ~/.bash_login gets executed. Rename the .bash_profile to something else. Re-login to make sure the Linux prompt changes to the PS1 value set inside the  ~/.bash_login as shown below.
~/.bash_profile> mv .bash_profile bash_profile_not_used

[Note: Upon re-login, it executed /etc/profile first.
Since it cannot find ~/.bash_profile, it executed ~/.bash_login]
Last login: Sat Sep 27 16:50:55 2008 from 192.168.1.2
~/bash_login>
4. ~/.profile gets executed. Rename the .bash_login to something else. Re-login to make sure the Linux prompt changes to the PS1 value set inside the  ~/.profile as shown below.
~/.bash_login> mv .bash_login bash_login_not_used

[Note: Upon re-login, it executed /etc/profile first.
Since it cannot find ~/.bash_profile and ~/.bash_login, it executed ~/.profile]
Last login: Sat Sep 27 16:56:36 2008 from 192.168.1.2
~/.profile>
5. ~/.bashrc gets executed for non-login shell testing. Executing bash” at the command prompt will give another non-login shell, which will invoke .bashrc as shown below.
~/.profile> bash

[Note: This displays PS1 from .bashrc as shown below.]
~/.bashrc> exit
exit

[Note: After exiting from non-login shell, we are back to login shell]
~/.profile>