Recognizing non-interactive shells and 'shell levels'
The issue of when bash sources your
.bashrc does raise
the obvious question of how you can tell in your
.bashrc what case
you're dealing with, so that you can do different things in each of
The traditional approach to do this is to set environment variables to
signal what state you're in and how many things have been initialized.
One traditional 'have I been initialized' variable is
$PS1, but this
has the tiny weakness that
su'ing to the account from another account
that already has
$PS1 set will not trigger your initializations.
(To keep clutter down, your 'am I a login shell' environment variable doesn't need to be exported, and indeed can be unset immediately after you use it. Other flag variables generally need to persist into future sub-shells.)
If you need to know interactive versus non-interactive, there are two
approaches. First, you can check the shell's built in
$- variable to
see if the '
i' flag is part of the shell's flags, and second, you can
test to see if standard input is connected to a terminal. Which
test is better depends in part on what you're trying to do; for example,
if you want to run
stty, you really care only about whether you're
hooked up to a terminal.
The good news about modern systems is that all of this is much less important than it used to be; these days the overhead of re-doing redundant initializations, even relatively complex ones, is usually pretty low.
(Netbooks and other small machines may yet change this back, of course.)