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 startup files to use. The next sections cover the two most popular Unix shells, bash and tcsh.
In bash, you have these startup filenames to choose from: .bash_profile, .profile, .bash_login, and .bashrc. Which one of these is appropriate to use 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.
The reason for this setup is that there are several different kinds of bash shell instance types, as follows:
Interactive shell The is the type of shell that you use to run commands from a terminal. There are two subtypes of interactive shells:
Login shell This is traditionally invoked by /bin/login; for example, when getty or sshd starts /bin/login. The exact circumstances that determine an interactive shell are a little strange (the first character of a login shell's invocation name is a -), but the basic idea is that the login shell is an initial shell. When bash runs as a login shell, it looks for a user's .bash_profile, .bash_login, and .profile files, running the first one that it sees.
Non-login shell This is any other interactive shell. Windowing system terminal programs (xterm, GNOME Terminal, and so on) start non-login shells unless you specifically ask for a login shell. bash reads from .bashrc upon startup of a non-login shell.
Non-interactive shell This is a shell that doesn't require input from aterminal.
The reasoning behind the two different startup file systems is that in the old days, users logged in through a traditional terminal with a login shell, then started non-login subshells with windowing systems or the screen program. It was deemed a waste to repeatedly set the user environment and run all sorts of wasteful programs in these subshells. 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.
That's a nice theory, but in these modern times, nearly everyone logs in through a graphical display manager that never starts a login shell. Therefore, you need to set up your entire environment (path, manual path, and so on) in your .bashrc, or you would 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 these are login shells, and they don't ever bother with .bashrc.
None of the issues described in the previous two paragraphs should matter, because it's never a good idea to make a complicated mess of your startup files, and modern hardware is so fast that a little extra work for every new shell shouldn't cause much of a performance hit anyway.
Here is a very elementary (yet perfectly sufficient) .bashrc that you can also share with your .bash_profile:
# Command path. PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:$HOME/bin # Manual page path. MANPATH=/usr/local/man:/usr/man:/usr/X11R6/man:$HOME/man # 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. LESS=mei # You must export environment variables. export MANPATH EDITOR VISUAL PAGER LESS # By default, give other users read-only access to most new files. umask 022
As described earlier, you can share this .bashrc file with .bash_profile via a symbolic link. One (possibly better) alternative is to create .bash_profile as this one-liner:
Now that your .bashrc matches your .bash_profile, you can no longer run extra commands for login shells. Therefore, 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 first character of the shell's $0 variable for a - character:
case $0 in -*) command command ... ... ;; esac
If, for whatever reason, you want to run certain commands only if a shell is interactive, use a construct like this in your .bashrc:
case "$-" in *i*) command command ... ... ;; esac
Normally, bash doesn't read startup files at all for non-interactive shells. The preceding code only applies if you set the BASH_ENV environment variable to a startup filename.
The standard csh on virtually all Linux systems is tcsh, an enhanced C shell that popularized features such as command-line editing and multimode filename and command completion. Even if you don't use tcsh as the default new user shell (this book suggests using bash), 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 adequately.
Here is sample .cshrc file:
# Command path. setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:$HOME/bin # Manual page path. setenv MANPATH /usr/local/man:/usr/man:/usr/X11R6/man:$HOME/man # 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 mei # 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%% "