Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

What's the difference between .bashrc and .bash_profile and which one should I use?

share|improve this question
1  
See also this similar question at ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile –  Stefan Lasiewski Sep 7 '10 at 18:38

3 Answers 3

up vote 233 down vote accepted

Traditionally, when you log into a Unix system, the system would start one program for you. That program is a shell, i.e., a program designed to start other programs. It's a command line shell: you start another program by typing its name. The default shell, a Bourne shell, reads commands from ~/.profile when it is invoked as the login shell.

Bash is a Bourne-like shell. It reads commands from ~/.bash_profile when it is invoked as the login shell, and if that file doesn't exist¹, it tries reading ~/.profile instead.

You can invoke a shell directly at any time, for example by launching a terminal emulator inside a GUI environment. If the shell is not a login shell, it doesn't read ~/.profile. When you start bash as an interactive shell (i.e., not to run a script), it reads ~/.bashrc (except when invoked as a login shell, then it only reads ~/.bash_profile or ~/.profile.

Therefore:

  • ~/.profile is the place to put stuff that applies to your whole session, such as programs that you want to start when you log in (but not graphical programs, they go into a different file), and environment variable definitions.

  • ~/.bashrc is the place to put stuff that applies only to bash itself, such as alias and function definitions, shell options, and prompt settings. (You could also put key bindings there, but for bash they normally go into ~/.inputrc.)

  • ~/.bash_profile can be used instead of ~/.profile, but it is read by bash only, not by any other shell. (This is mostly a concern if you want your initialization files to work on multiple machines and your login shell isn't bash on all of them.) This is a logical place to include ~/.bashrc if the shell is interactive. I recommend the following contents in ~/.bash_profile:

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

On modern unices, there's an added complication related to ~/.profile. If you log in in a graphical environment (that is, if the program where you type your password is running in graphics mode), you don't automatically get a login shell that reads ~/.profile. Depending on the graphical login program, on the window manager or desktop environment you run afterwards, and on how your distribution configured these programs, your ~/.profile may or may not be read. If it's not, there's usually another place where you can define environment variables and programs to launch when you log in, but there is unfortunately no standard location.

Note that you may see here and there recommendations to either put environment variable definitions in ~/.bashrc or always launch login shells in terminals. Both are bad ideas. The most common problem with either of these ideas is that your environment variables will only be set in programs launched via the terminal, not in programs started directly with an icon or menu or keyboard shortcut.

¹ For completeness, by request: if .bash_profile doesn't exist, bash also tries .bash_login before falling back to .profile. Feel free to forget it exists.

share|improve this answer
5  
+1 for good post. ALSO thank you for adding section about "login graphical vs login shell"... I had the problem where I thought ~/.profile would ALWAYS execute for graphical/shell... but it doesn't execute for when the user logs in via graphical login. Thank you for solving that mystery. –  Trevor Boyd Smith Sep 17 '11 at 21:41
1  
@Gilles: Could you explain in more detail, with examples, of why running a login shell in every terminal is a bad idea? Is this only an issue with desktop Linux? (I gather that on OS X Terminal runs a login shell every time, and I've never noticed any side effects (though I usually use iTerm). But then I can't think of many environment variables I'd care about outside of a terminal. (Maybe HTTP_PROXY?)) –  iconoclast Jun 12 '12 at 16:38
1  
@Brandon If you run a login shell in every terminal, that will override environment variables provided by the environment. In everyday situations, you can get away with it, but it'll come and bite you sooner or later, when you want to set up different variables in a terminal (say, to try out a different version of a program): running a login shell would override your local settings. –  Gilles Jun 12 '12 at 17:57
2  
The statement ~/.bash_profile can be used instead of ~/.profile, but you also need to include ~/.bashrc if the shell is interactive. is misleading as these are orthogonal issues. No matter if you use ~/.bash_profile or ~/.profile you have to include ~/.bashrc in the one you use if you want settings from there to have effect in the login shell. –  Piotr Dobrogost Jun 15 '13 at 11:20
1  
@Gilles Sure, but the way the sentence is formulated in the answer suggests that the need to include ~/.bashrc has something to do with choosing ~/.bash_profile instead of ~/.profile which is not true. If someone includes ~/.bashrc in any kind of script being sourced at login time (here it's either ~/.bash_profile or ~/.profile) is because he wants settings from ~/.bashrc to be applied to the login shell the same way they are being applied to non-login shell. –  Piotr Dobrogost Jun 15 '13 at 12:29

From this short article

According to the bash man page, .bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.

What is a login or non-login shell?

When you login (eg: type username and password) via console, either physically sitting at the machine when booting, or remotely via ssh: .bash_profile is executed to configure things 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.

share|improve this answer
8  
Slight updates: 'Executed' is probably a slightly misleading term, they're both sourced. Executed sounds like it's run as a script, fork/exec yadda yadda. It's run in the context of the current shell More importantly, .bashrc is run much more often. It is run on every bash script run, and also if you don't have a .bash_profile. Also, depending how you set up your xterms, you may create a shell that sources .bash_profile –  Rich Homolka Sep 2 '10 at 17:57

Back in the old days, when pseudo tty's weren't pseudo and actually, well, typed, and UNIXes were accessed by modems so slow you could see each letter being printed to your screen, efficiency was paramount. To help efficiency somewhat you had a concept of a main login window and whatever other windows you used to actually work. In your main window, you'd like notifications to any new mail, possibly run some other programs in the background.

To support this, shells sourced a file .profile specifically on 'login shells'. This would do the special, once a session setup. Bash extended this somewhat to look at .bash_profile first before .profile, this way you could put bash only things in there (so they don't screw up Bourne shell, etc, that also looked at .profile). Other shells, non-login, would just source the rc file, .bashrc (or .kshrc, etc).

This is a bit of an anachronism now. You don't log into a main shell as much as you log into a gui window manager. There is no main window any different than any other window.

My suggestion - don't worry about this difference, it's based on an older style of using unix. Eliminate the difference in your files. The entire contents of .bash_profile should be:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

And put everything you actually want to set in .bashrc

Remember that .bashrc is sourced for all shells, interactive and non-interactive. You can short circuit the sourcing for non-interactive shells by putting this code near the top of .bashrc:

[[ $- != *i* ]] && return

share|improve this answer
4  
This is a bad idea, see my answer. In particular, your environment variables will only be set in programs launched via the terminal, not in programs started directly with an icon or menu or keyboard shortcut. –  Gilles Sep 2 '10 at 19:24
4  
@Gilles I don't understand why you claim this. With .$HOME/.bashrc as Rich showed above, settings in .bashrc will be available in login shells, and thus the desktop environment as well. For example, on my Fedora system, gnome-session is started as -$SHELL -c gnome-session, so .profile is read. –  Mikel Jun 2 '12 at 16:25
    
@Gilles Do you care to comment on Mikel's remark? –  Piotr Dobrogost Jun 15 '13 at 9:30
3  
@Gilles re: "including .bashrc in .profile" is not at all what was recommended (quite the contrary, in fact). Either the answer was edited (it doesn't appear so), or your comments don't align with what is being said. –  michael_n Jul 29 '13 at 6:17
1  
+1 Very clear and simple explanation (maybe I'm just lazy, but I don't think the accepted answer is as clear as yours). –  rsenna Aug 27 '13 at 22:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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