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.

In an attempt to "properly" implement a standard configuration of my preferred shell, bash, for use across multiple platforms, I've come across some confusion when dealing with terminals that are inconsistent with their choice of shell start-up types (login or interactive).

Bash Start-Up Files

From the bash manual, I've determined the difference between the start-up files and order/cases in which they are sourced (/etc/profile, ~/.bash_profile, ~/.bash_login, and ~/.profile for login shells, and ~/.bashrc for interactive non-login shells). The documentation suggested that you store your bash-specfic login configuration in ~/.bash_profile and your bash-specific interactive ones in your ~/.bashrc. The manual itself even suggested adding if [ -f ~/.bashrc ]; then source ~/.bashrc; fi to the ~/.bash_profile file so login shells inherit your interactive shell settings.

From what I've read in the manual and in various online forums/docs, it also seemed prudent to abstract your non-bash specific login configuration to ~/.profile since other shells can source this file. This may be an edge-case for people who may use Bourne shell in addition to bash (which is not really likely in my case), but it seems like a good habit to form.

So far this all seems pretty straight forward and logical, especially in an environment where the distinction between the various shell start-up types are apparent: on systems or terminals where the command-line is the primary interface, login shells are your primary session shells, interactive shells are subsequent shells launched in that session, and your non-interactive shells are script-running shells.

The real confusion is what constitutes a login shell when your shell is started from a terminal within a GUI environment where you are already authenticated to the system? It seems to me that the default behavior in Mac OSX Terminal.app is for the shell running in each window to start a login shell, whereas in xterm, each new window is an interactive shell.


It is possible that I am seeing a problem where one does not exist, however consider the following: the terminal situation suggests that I put the vast majority of my configuration in ~/.bashrc to avoid losing functionality should I be working on a terminal that starts bash as an interactive shell. Being unfamiliar with the intricacies of when bash might be spawned as interactive shells, I have to rely on this statement that abusing ~/.bashrc like this will eventually cause problems where login shell configuration being misplaced is detrimental to normal shell functioning. It isn't hard to imagine that problems might arise when you ignore the manual's advice and use configuration files inappropriately.

Since you can't really rely on using ~/.bashrc as your catch-all, it seems like you might need to treat your ~/.bash_profile and ~/.bashrc files differently depending on the terminal you are using. This seems like it would result in a lot of headaches and is counter to the purpose of having these distinct start-up files in the first place!

So finally my questions are as follows:

  • How do current Bash shell users address the issue of GUI terminal inconsistencies between starting login and interactive shells?
  • How do you create a single-set of bash start-up files for cross-platform (and cross-terminal) use, without running into problems?

Thank you for your assistance and advice.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

The most common problem caused by misuse of shell startup files is that if you define environment variables in .bashrc as opposed to .profile, they are not defined in applications that are not launched from a shell in a terminal but rather from a GUI menu.

Defining environment variables from .bashrc is generally not a good idea, but that's primarily because it's generally useless as the variables should already have been set at login time. It can cause a problem in practice if you (or an application) have deliberately changed the value of a variable (e.g. PATH) in a program and you launch a shell from that program and expect the setting to have remained the same.

You can avoid the problem of environment variables being reset by defining a “sentinel” value, and not defining anything if the sentinel value is set:

if [ -z "$JMLANE_PROFILE_READ" ]; then
  export ...
  export JMLANE_PROFILE_READ=1
fi

Another problem caused by terminals starting login shells is that there are things that should only be done once when you log in, for example starting a password agent (e.g. ssh-agent), or initiating a session (e.g. running startx in certain circumstances). The sentinel variable avoids these issues.

A shell inside a terminal is always interactive. As long as you source .bashrc from .bash_profile when the shell is interactive, you don't need to worry about the terminal starting a login shell.

An additional wart of bash's startup file handling is that .bashrc is read by non-interactive shells invoked by rshd or sshd. For example, when you do rsync somefile host.example.com:, if your login shell on host.example.com is bash, you can use .bashrc there to set the path to include rsync. You can tell you're in this situation because .bashrc is read from a non-interactive shell.

## .bashrc
if [[ $- != *i* ]]; then
  # either .bashrc was executed explicitly or this is a noninteractive rsh/ssh session
fi
share|improve this answer
    
So with the exception of setting environment variables in .bash_profile (which sources .bash_rc), there isn't much of a problem with using .bash_profile and .bash_rc both in both a login shell and a non-login interactive shell? –  jmlane Dec 5 '10 at 0:51
    
I may have to do some research into edge-cases where non-interactive shells may source .bashrc for some odd reason. As you've described it, this seems like a bug in rshd (less so for sshd), so I need to determine why this behaviour persists in the latest version of that software. –  jmlane Dec 5 '10 at 0:53
    
@jmlane: It has nothing to do with rshd or sshd, it's a documented bash peculiarity (see also run_startup_files in shell.c in the bash source). –  Gilles Dec 5 '10 at 17:36
    
Given the time since you answered, I've expanded my practical knowledge of Bash and I've come to appreciate the points you illustrated in your answer. Because of this guidance, I have yet to run into any unexpected behaviour due to misplaced commands or statements in my Bash start-up files. –  jmlane Oct 30 '11 at 16:47

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.