13.4 Startup File Order and Examples
Now that you know what to put into shell startup files, it’s time to see some specific examples. Surprisingly, one of the most difficult and confusing parts of creating startup files is determining which of several possible startup files to use. This section covers the two most popular Unix shells: bash and tcsh.
13.4.1 The bash Shell
In bash, you can choose from the startup filenames .bash_profile, .profile, .bash_login, and .bashrc. Which one is appropriate for your command path, manual page path, prompt, aliases, and permissions mask? The answer is that you should have a .bashrc file accompanied by a .bash_profile symbolic link pointing to .bashrc because there are a few different kinds of bash shell instance types.
The two main shell instance types are interactive and noninteractive, but we’re interested only in interactive shells, because noninteractive shells (such as those that run shell scripts) usually don’t read any startup files. Interactive shells are those you use to run commands from a terminal, such as the ones you’ve seen in this book, and they can be classified as login or non-login.
Login Shells
Traditionally, a login shell is what you get when you first log in to a system with the terminal using a program such as /bin/login. Logging in remotely with SSH also gives you a login shell. The basic idea is that the login shell is an initial shell. You can tell if a shell is a login shell by running echo $0; if the first character is a -, the shell’s a login shell.
When bash runs as a login shell, it runs /etc/profile. Then it looks for a user’s .bash_profile, .bash_login, and .profile files, running only the first one that it sees.
As strange as it sounds, it’s possible to run a noninteractive shell as a login shell to force it to run startup files. To do so, start the shell with the -l or --login option.
Non-Login Shells
A non-login shell is an additional shell that you run after you log in. It’s simply any interactive shell that’s not a login shell. Windowing system terminal programs (xterm, GNOME Terminal, and so on) start non-login shells unless you specifically ask for a login shell.
Upon starting up as a non-login shell, bash runs /etc/bash.bashrc and then runs the user’s .bashrc.
The Consequences of Two Kinds of Shells
The reasoning behind the two different startup files is that in the old days, users logged in through a traditional terminal with a login shell, and then started non-login subshells with windowing systems or the screen program. For the non-login subshells, it was deemed a waste to repeatedly set the user environment and run a bunch of programs that had already been run. With login shells, you could run fancy startup commands in a file such as .bash_profile, leaving only aliases and other “lightweight” things to your .bashrc.
Nowadays, most desktop users log in through a graphical display manager (you’ll learn more about these in the next chapter). Most of these start with one noninteractive login shell in order to preserve the login versus non-login model. When they do not, you need to set up your entire environment (path, manual path, and so on) in your .bashrc, or you’ll never see any of your environment in your terminal window shells. However, you also need a .bash_profile if you ever want to log in on the console or remotely, because those login shells don’t ever bother with .bashrc.
Example .bashrc
In order to satisfy both non-login and login shells, how would you create a .bashrc that can also be used as your .bash_profile? Here’s one very elementary (yet perfectly sufficient) example:
# Command path.
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
PATH=$HOME/bin:$PATH
# PS1 is the regular prompt.
# Substitutions include:
# \u username \h hostname \w current directory
# \! history number \s shell name \$ $ if regular user
PS1='\u\$ '
# EDITOR and VISUAL determine the editor that programs such as less
# and mail clients invoke when asked to edit a file.
EDITOR=vi
VISUAL=vi
# PAGER is the default text file viewer for programs such as man.
PAGER=less
# These are some handy options for less.
# A different style is LESS=FRX
# (F=quit at end, R=show raw characters, X=don't use alt screen)
LESS=meiX
# You must export environment variables.
export PATH EDITOR VISUAL PAGER LESS
# By default, give other users read-only access to most new files.
umask 022
In this startup file, the path has $HOME/bin at the front so that executables there take precedence over the system versions. If you need the system executables, add /sbin and /usr/sbin.
As described earlier, you can share this .bashrc file with .bash_profile via a symbolic link, or you can make the relationship even clearer by creating .bash_profile as this one-liner:
. $HOME/.bashrc
Checking for Login and Interactive Shells
With a .bashrc matching your .bash_profile, you don’t normally run extra commands for login shells. However, if you want to define different actions for login and non-login shells, you can add the following test to your .bashrc, which checks the shell’s $- variable for an i character:
case $- in
*i*) # interactive commands go here
command
--snip--
;;
*) # non-interactive commands go here
command
--snip--
;;
esac
13.4.2 The tcsh Shell
The standard csh on virtually all Linux systems is tcsh, an enhanced C shell that popularized features such as command-line editing and multi-mode filename and command completion. Even if you don’t use tcsh as the default new user shell (bash should be the default), you should still provide tcsh startup files in case your users happen to come across tcsh.
You don’t have to worry about the difference between login shells and non-login shells in tcsh. Upon startup, tcsh looks for a .tcshrc file. Failing this, it looks for the csh shell’s .cshrc startup file. The reason for this order is that you can use the .tcshrc file for tcsh extensions that don’t work in csh. You should probably stick to using the traditional .cshrc instead of .tcshrc; it’s highly unlikely that anyone will ever use your startup files with csh. And if a user actually does come across csh on some other system, your .cshrc will work.
Example .cshrc
Here is a sample .cshrc file:
# Command path.
setenv PATH $HOME/bin:/usr/local/bin:/usr/bin:/bin
# EDITOR and VISUAL determine the editor that programs such as less
# and mail clients invoke when asked to edit a file.
setenv EDITOR vi
setenv VISUAL vi
# PAGER is the default text file viewer for programs such as man.
setenv PAGER less
# These are some handy options for less.
setenv LESS meiX
# By default, give other users read-only access to most new files.
umask 022
# Customize the prompt.
# Substitutions include:
# %n username %m hostname %/ current directory
# %h history number %l current terminal %% %
set prompt="%m%% "