I've used a number of different *nix-based systems of the years, and it seems like every flavor of Bash I use has a different algorithm for deciding which startup scripts to run. For the purposes of tasks like setting up environment variables and aliases and printing startup messages (e.g. MOTDs), which startup script is the appropriate place to do these?
What's the difference between putting things in .bashrc
, .bash_profile
, and .environment
? I've also seen other files such as .login
, .bash_login
, and .profile
; are these ever relevant? What are the differences in which ones get run when logging in physically, logging in remotely via ssh, and opening a new terminal window? Are there any significant differences across platforms (including Mac OS X (and its Terminal.app) and Cygwin Bash)?
That's simple. It's explained in
man bash
:Login shells are the ones that are read one you login (so, they are not executed when merely starting up xterm, for example). There are other ways to login. For example using an X display manager. Those have other ways to read and export environment variables at login time.
Also read the
INVOCATION
chapter in the manual. It says "The following paragraphs describe how bash executes its startup files.", i think that's a spot-on :) It explains what an "interactive" shell is too.Bash does not know about
.environment
. I suspect that's a file of your distribution, to set environment variables independent of the shell that you drive.I found information about .bashrc and .bash_profile here to sum it up:
Also there is a complete follow up on each of the configurations files here
These are probably even distro.-dependant, not all distros choose to have each configuraton with them and some have even more. But when they have the same name, they usualy include the same content.
A good place to look at is the man page of bash. Here's an online version. Look for "INVOCATION" section.
I have used Debian-family distros which appear to execute
.profile
, but not.bash_profile
, whereas RHEL derivatives execute.bash_profile
before.profile
.It seems to be a mess when you have to set up environment variables to work in any Linux OS.
According to Josh Staiger, Mac OS X's Terminal.app actually runs a login shell rather than a non-login shell by default for each new terminal window, calling .bash_profile instead of .bashrc.
He recommends:
The main difference with shell config files is that some are only read by "login" shells (eg. when you login from another host, or login at the text console of a local unix machine). these are the ones called, say,
.login
or.profile
or.zlogin
(depending on which shell you're using).Then you have config files that are read by "interactive" shells (as in, ones connected to a terminal (or pseudo-terminal in the case of, say, a terminal emulator running under a windowing system). these are the ones with names like
.bashrc
,.tcshrc
,.zshrc
, etc.bash
complicates this in that.bashrc
is only read by a shell that's both interactive and non-login, so you'll find most people end up telling their.bash_profile
to also read.bashrc
with something like[[ -r ~/.bashrc ]] && . ~/.bashrc
Other shells behave differently - eg with
zsh
,.zshrc
is always read for an interactive shell, whether it's a login one or not.The manual page for bash explains the circumstances under which each file is read. Yes, behaviour is generally consistent between machines.
.profile
is simply the login script filename originally used by/bin/sh
.bash
, being generally backwards-compatible with/bin/sh
, will read.profile
if one exists.