/etc/profile is invoked only for login shells because that is its specific purpose.
If you want a command to run for interactive shells that are not login shells, and you're using
bash, put it in
The purpose of the "profile" files is to contain commands that ought to be run for login shells only. These files are:
/etc/profile, run by all Bourne-compatible shells (including
dash) when started as a login shell.
This is for Bourne-style shells, but it's not coded into the shell executable itself. Rather, commands in
/etc/profile calls them. For example, on my Ubuntu 12.04 system,
/etc/profile includes these lines:
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
.profile in the user's home directory, run by Bourne-compatible shells when started as a login shell (unless overridden, see below).
.bash_login in the user's home directory. These are ignored by shells other than
bash. But if
bash runs it instead of
.bash_profile doesn't exist but
.bash_login exists, that is run instead of
(But it is common for
.bash_login, when it exists, to be written so as to *explicitly call
The benefit of shell-specific profile files is that they can contain commands or syntax that are only valid for that shell. For example, I can use the
[[ evaluation operator in
.bash_login but if I use it in
.profile and then log in with
dash as my shell, it will fail.
What Should Go In "profile" Files
"profile" files should contain commands that ought only run once, at the beginning of login. (This includes graphical logins, as they start with a login shell, too.) If a shell is interactive, the user running it is probably logged on, and so it probably has an ancestor (that started it, or started what started it, or started that, etc.) that was a login shell.
You might want to run a command only once because:
- there is no reason to run it more than one time per login, it would be inefficient, or
- it would produce an undesired result, to run it more than once per login.
As an example of the second situation, where an undesirable result would occur, consider these lines, which appear by default in every user's
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
Suppose you SSH'd in, ran another shell (say,
zsh), at some point found you wanted to temporarily go back to
bash but keep your environment (so ran
bash again while in
zsh), and then ran a program like
mc that runs a shell as part of its interface. If
bin exists in your home folder and your username is
PATH in the innermost shell is something like:
That's inefficient and (much more importantly) makes it hard to understand the contents of
This is by no means a disaster, though. As far as I can tell, if every interactive shell sourced "profile" files, nothing terrible would happen, in the default configuration. However, since the purpose of "profile" files is to contain commands to just run once per login, a user or administrator may add commands to a profile that must only run when starting a login shell.
Where to Put Commands for Every Interactive Shell to Run
If you are using
bash, there are files for commands that are to be run in every interactive shell:
.bashrc in the user's home directory.
This is most commonly used for commands that
- affect only the environment of the shell in which they run--not even child shells, or
- ought to run even when this is not the login shell.
For example, command-line tab-completion should generally be enabled whether or not
bash was the login shell. So this appears in
if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
There, 1 and 2 both apply: this does not carry over to other shells run inside this one, and tab-completion should work in
bash even if I logged in with a different shell.
Where to Put Commands for Login Shells and Interactive non-Login Shells
If you're using
bash and want a command to run in login shells and interactive shells and that are not login shells, it is generally sufficient to put it in
~/.bashrc. This is because, by default,
~/.profile run them explicitly. For example,
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
Thus both "profile" and "rc" files run when you start an interactive
bash shell (whether or not it's a login shell).
Where to Put Commands to Run in non-Interactive Shells
You probably do not want to specify any commands for all non-interactive shells to run; they would run every time a script is run (provided the script is run by the shell you configure to run them).
This can cause substantial breakage. If you're going to do this, and there is not an administrator account on the system besides the one you're using, you might want to create one; that can make it easier to fix mistakes.
bash, the "rc" files are actually run whether the shell is interactive or not. However, at the top they say:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
So, if you need commands to run automatically even in non-interactive shells like the ones that run to execute scripts, you can add your commands before those lines.
Starting a Login Shell
Logging in starts a login shell. If you want a shell started after that to behave as a login shell, start it with the
-l flag (stands for login). For example:
That's the best way to start a login shell (without logging in) unless you want to start one as another user. Then, use:
sudo -i for
sudo -s for a non-login, interactive root shell)
sudo -u username -i for any user
su - username for non-
root users (use
su username for a non-login, interactive root shell)
What's an initial login shell?
An initial login shell is the same as a login shell. Everywhere this answer says "login shell" it could say "inital login shell" (except in this section, which would already have stoped making sense).
One reason for the term inital login shell is that login shell is also used in a different sense--to identify which program is used as the shell that is executed by logging on. This is the sense of login shell used to say:
- "OpenBSD's default login shell is
ksh; in Ubuntu, it's
- "You can change your login shell with