The three files are read in this order?


This is not happening when I first open a terminal.

I have trace statements in the files appending to the file init.log. Please take a look at the following. It begins after opening a terminal. I have placed a comment to show where the log picks up after the su command.

stephen@debian:~$ cat init.log
reading .bashrc
done reading .bashrc
stephen@debian:~$ su - stephen
stephen@debian:~$ cat init.log
reading .bashrc
done reading .bashrc
# after su
reading .bash_profile
reading .profile
reading .bashrc
done reading .bashrc
done reading .profile
done reading .bash_profile

So the su - login triggers the expected sequence however the initial login reads only the bashrc. This cannot be correct. Can someone explain under what conditions this would occur. I could modify the bashrc and profile files so that the initial read includes all expected files but I would rather get to the root of the problem and fix it there.


The answer is that bash will look for these three files (in slightly different situations) but will typically only execute one of them.

When running a login shell (typically when you log in on a terminal, or when you open a GNOME Terminal or similar, or when you use su -), more specifically an interactive login shell, then it will execute the system-wide /etc/profile and after that's done, it will look for ~/.bash_profile, ~/.bash_login or ~/.profile and execute the first of those that it finds.

From the bash man page:

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 bash is executed as an interactive shell, more specifically an interactive non-login shell, then it will read ~/.bashrc and execute that file.

From the bash man page:

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.

What Linux distributions usually do is ship ~/.bash_profile, ~/.profile and ~/.bashrc files that chain each other, so that you have more consistent behavior without having to duplicate settings between the files...

For instance, Debian's default ~/.profile contains this snippet:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"

So it's explicitly sourcing ~/.bashrc, so that both login and non-login interactive shells will all include the customizations added to that file.

  • Thank you @Felipe for this thoughtful and instructive response. On opening a terminal (mate-terminal, xterm) I am starting an interactive login shell, correct? And so I should see .bash_profile, .bash_login, .profile in that order but I see only .bashrc. On an su - we read in .bash_profile (if it exists) or if it does not exist then .profile which pulls in .bashrc. So does this mean that when I start a terminal that I am NOT starting an interactive login shell, but that when I su in that session or when I ssh in I DO start an interactive login shell? Why that distinction?. Apr 21 '18 at 18:03
  • 1
    @StephenBoston yes it's possible that the terminal will give you a non-login interactive shell. Terminals are a blurry area (since you log in into the GUI), many of them offer to configure whether to open a login shell or not. Also commands have that distinction too (su - gives you a login shell while plain su doesn't, sudo -i gives you a login shell while sudo -s gives you a non-interactive login shell.) In general, best you can do is ignore that difference, have your .profile source .bashrc (which is usually done by the distro) and configure everything in .bashrc.
    – filbranden
    Apr 22 '18 at 5:15
  • I have copied the PATH setting snippet from the .profile file into the .bashrc and that seems to work. My HOME/bin is added to the PATH for those situations I expect it. However I will keep an eye on it. Apr 22 '18 at 18:43
  • @StephenBoston see also this answer: superuser.com/a/183980/879179. Some graphical environments can be configured to read your ~/.profile or ~/.bash_profile, that's probably the best answer... But it's a different question, so maybe you should post that one for your specific graphical environment setup...
    – filbranden
    Apr 23 '18 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.