Login and non-login shell defined as:
su - $USER # will give you a login shell
bash # will give you a non-login shell
/etc/profile is not invoked for non-login shells, such as when you start konsole (kde). /etc/profile is only invoked for login shells.
Why is that? Please explain, because I like to understand the rationale of this.
Best Answer
/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~/.bashrc
or/etc/bash.bashrc
.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 (includingbash
anddash
) when started as a login shell.Scripts in
/etc/profile.d
.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:.profile
in the user's home directory, run by Bourne-compatible shells when started as a login shell (unless overridden, see below)..bash_profile
or.bash_login
in the user's home directory. These are ignored by shells other thanbash
. But if.bash_profile
exists,bash
runs it instead of.profile
. If.bash_profile
doesn't exist but.bash_login
exists, that is run instead of.profile
.(But it is common for
.bash_profile
or.bash_login
, when it exists, to be written so as to *explicitly call.profile
.)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_profile
/.bash_login
but if I use it in.profile
and then log in withdash
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:
As an example of the second situation, where an undesirable result would occur, consider these lines, which appear by default in every user's
~/.profile
:Suppose you SSH'd in, ran another shell (say,
zsh
), at some point found you wanted to temporarily go back tobash
but keep your environment (so ranbash
again while inzsh
), and then ran a program likemc
that runs a shell as part of its interface. Ifbin
exists in your home folder and your username isjames
, yourPATH
in the innermost shell is something like:That's inefficient and (much more importantly) makes it hard to understand the contents of
PATH
.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:/etc/bash.bashrc
.bashrc
in the user's home directory.This is most commonly used for commands that
For example, command-line tab-completion should generally be enabled whether or not
bash
was the login shell. So this appears in~/.bashrc
: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/etc/bash.bashrc
or~/.bashrc
. This is because, by default,/etc/profile
and~/.profile
run them explicitly. For example,~/.profile
has:(Similarly,
/etc/profile
sources/etc/bash.bashrc
forbash
.)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.
In
bash
, the "rc" files are actually run whether the shell is interactive or not. However, at the top they say: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:sh -l
bash -l
pdksh -l
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
forroot
(usesudo -s
for a non-login, interactive root shell)sudo -u username -i
for any usersu - username
for non-root
users (usesu 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:
ksh
; in Ubuntu, it'sbash
."chsh
."Further Reading
bash
manpage