Chapter 4. The Shell Startup Files

In This chapter:

  • Startup and Shutdown Files

  • Getting To Know .cshr c and .login

  • Modifying .cshrc and .login

  • Using Variables

  • Organizing Your Startup Files

  • The .logout File

When you log in, your shell doesn’t operate in a vacuum. Its behavior is affected by your working environment, which includes:

  • Terminal settings, such as your backspace and line kill characters

  • Variable values

  • Aliases

  • Key bindings for the command-line editor (tcsh only)

  • Programmed completions (tcsh only)

All of the above are initialized in the shell startup files.

This chapter provides guidelines for modifying your startup files, explains how to set variables, and describes how to organize startup file contents. It’s important to understand and know how to modify these files, since your working environment strongly influences how easily you get your work done. Much of the shell’s power is tapped by using your startup files to set up your environment the way you like.

Startup and Shutdown Files

When you log in, your shell sets up its environment by reading two files named .cshrc and .login from your home directory. If the files exist, the shell executes their commands before displaying its first prompt.

tcsh reads startup files a little differently than csh. If you have a file named .tcshrc in your home directory, tcsh reads that instead of .cshrc. In order to avoid repeating a qualifying phrase throughout this handbook, it should be understood that references to .cshrc mean ".tcshrc if it exists and you’re using tcsh, .cshrc otherwise.” Any exceptions to this convention will be clear from the context.

In this chapter, I assume that you are in your home directory, and I refer to the startup files as .cshrc and .login. Elsewhere, I make no such assumption and refer to the files as ˜/.cshrc and ˜/.login, to indicate explicitly that they’re located in your home directory.

Your shell might also read system-wide startup files before reading the startup files in your home directory. Not all versions of the shell read system-level files, and the names of the files vary from system to system (they might be named /etc/csh.cshrc and /etc/csh.login, for instance). System administrators sometimes use these files to standardize aspects of the working environment across accounts. You can either leave those settings in place, or use commands like unset, unsetenv, unalias, and uncomplete to remove them.

If a .logout file exists in your home directory, the shell reads commands from it when you log out. Your shell might also read a system-wide file such as /etc/csh.logout before reading the one in your home directory. Like /etc/csh.cshrc and /etc/csh.login, /etc/csh.logout can be used by system administrators.

Getting To Know .cshrc and .login

If you’re not familiar with your .cshrc and .login files, you should run the ls command in your home directory to find out if they exist. Specify the –a (“show all”) option since ls doesn’t normally show dot files (files with names that begin with a period):

% ls -a
.           .cshrc     .mailrc    Letters      Papers    calendar   src
..          .exrc      .msgsrc    Mail         Projects  junk       tmpfile
.Xdefaults  .login     .plan      Misc         bin       mbox

If you don’t have .cshrc and .login files, you can create them with any text editor, but it’s likely that generic versions of .cshrc and .login were installed in your home directory when your account was created. The generic versions might look something like this:

% more .cshrc
if ($?prompt) then
    set prompt = "% "
    set history = 20
    set cdpath = ( ˜ ˜/Projects ˜/Papers )
alias h history
alias ll ls -l
alias print 'pr \!* | lpr'
set path = ( /bin /usr/bin /usr/ucb ˜/bin . )
% more .login
tset -I -Q
stty erase ^h intr ^c
setenv TERM vt100
biff y

It’s okay if you don’t understand the contents of .cshrc and .login the first time you look at them, but you should strive to understand them eventually. If you see commands in your startup files that you’re not familiar with, check for them in the index of this handbook, read their manual pages, or ask a knowledgeable user on your system about them. Also, it’s a good idea to see how other people use their startup files. Ask more experienced users for copies of their files, and ask them to explain the parts that you don’t understand. You may even decide to copy some of what you find into your own files.

Modifying .cshrc and .login

You can modify your working environment immediately by typing commands at the command line, but changes made that way disappear as soon as you log out. To make sure that a command is run each time you log in, add it to one of your shell’s startup files using a text editor such as vi or emacs. The changes take effect the next time you log in.

Some guidelines for modifying your startup files are given below. Follow them to avoid making trips to your system administrator after you’ve messed up a startup file to the point where you can’t log in:

  • Before modifying a startup file, make a copy:

    % cp .cshrc cshrc.orig             (or)
    % cp .login login.orig

    That way, you can restore it later, if necessary:

    % cp cshrc.orig .cshrc             (or)
    % cp login.orig .login
  • Before adding a command to a startup file, try it from the command line to make sure that it works.

  • Make one change at a time. If you change several things at once and something goes wrong, you’ll have a hard time tracking down the problem.

  • The shell treats lines that begin with # as comments and ignores them. Use this feature to add comments that document your modifications. These comments will help you remember why you made your changes when you review your startup files later on.

  • Don’t blithely delete commands you don’t understand; they might be important. If you want to see what happens when a particular command is not executed, turn it into a comment by putting a # in front of it. If, later on, you want to undo the change, just remove the #.

  • After modifying a startup file, try it out. But don’t do that by logging out and logging back in—establish a separate login session instead. That way, if there is a problem, you find out immediately, but you still have your original login session (running in your original environment), so that you can fix it. This is especially important if you introduce a serious error into a startup file that prevents further logins! You can use rlogin or telnet to log in again without terminating your current login session, pop up another xterm window (if you’re using the X Window System), or even go to another terminal.

    Verify that you can log in successfully and that your changes have the desired effect. If the shell seems to process only part of a startup file when you log in, be alert for error messages, and try to determine at what point in the execution of the file commands stop being processed. You will probably find a command with an error in it right before that point.

  • Finally, as you gain experience modifying .cshrc and .login, you’ll know when to ignore the preceding guidelines. For example, you may modify a startup file and feel confident it’s error free. You can then use the source command to tell your current shell to reprocess it, rather than logging in again:

    % source .cshrc                    (or)
    % source .login

Using Variables

Variables control shell behavior, including the prompt display, where to look for commands, and whether to maintain a history list. The shell understands two kinds of variables: shell variables and environment variables. In general, shell variables are used internally by the shell and affect its own operation, whereas environment variables are accessible to programs started from the shell. Appendix B, csh and tcsh Quick Reference, lists several useful variables of each type.

Variables can be set directly from the command line, but you’ll usually set them in your startup files, either to override default values that the shell supplies, or to define variables that the shell leaves undefined.

Shell Variables

Use the set command to define shell variables. Some variables need no explicit value; they have an effect merely by existing:

set notify                       Turn on immediate notification of job completion
set ignoreeof                    Disable logging out via CTRL-D

Other variables require a value:

set history = 20                 Tell shell to remember the last 20 commands
set prompt = "% "                Define command line prompt
set fignore = (.o .bak)          Specify suffixes to ignore during filename completion
set term = vt100                 Specify terminal type

Values that contain spaces or other special characters should be put in quotes, as in the set prompt command above. Values consisting of multiple strings must be surrounded with parentheses, as in the set fignore command.

You don’t need to have spaces around the = separating the variable name from the value. If you do, there must be spaces on both sides:

set history= 20                  Illegal
set history =20                  Illegal
set history=20                   Legal
set history = 20                 Legal

I prefer to use spaces because I find set commands more readable that way.

Environment Variables

Use setenv to define environment variables:

setenv TERM vt100                Specify terminal type
setenv PAGER /usr/ucb/more       Specify preferred output pager
setenv EDITOR /usr/bin/emacs     Specify preferred editor

Notice that, unlike set, setenv has no = between the variable name and its value.

Environment variables differ from shell variables in that, although their values are known by the shell, those values are also accessible to programs you run from the shell. (For example, if your mailer allows you to drop into an editor to edit a message, it might determine which editor to use by consulting the EDITOR environment variable.) Environment variable names are usually in uppercase type. Uppercase is not a requirement, but is a useful convention that helps distinguish environment variables from shell variables.

Examining and Using Variable Values

Use set or setenv with no argument to see the values of all your shell or environment variables:

% set                              Display all shell variables
% setenv                           Display all environment variables

Some systems have env or printenv commands that act like setenv.

A reference to a variable name is written $name or ${name}. You can examine individual variable values using echo:

% echo $TERM $path                 Display terminal type and command search path
% echo ${TERM} ${path}             This is equivalent to the above command

If you try to use a variable that doesn’t exist (i.e., has not been defined), the shell complains:

% echo $junk
junk: Undefined variable.

If a variable refers to a filename, you can apply one of the modifiers shown in Table 4-1 to extract different parts of the value. Modifiers are applied using the syntax $name:m or ${name:m}:

% set xyz = /etc/csh.cshrc

% echo root $xyz:r extension $xyz:e head $xyz:h tail $xyz:t
root /etc/csh extension cshrc head /etc tail csh.cshrc

% echo root ${xyz:r} extension ${xyz:e} head ${xyz:h} tail ${xyz:t}
root /etc/csh extension cshrc head /etc tail csh.cshrc
Table 4-1. Variable Modifiers




Root of value (everything but extension following dot)


Extension of value (suffix following dot)


Head of value (all but last pathname component)


Tail of value (last pathname component)

Turning Off Variables

If you want to turn off a shell or environment variable, use unset or unsetenv:

unset mail              Turn off notification of new mail
unsetenv DISPLAY        Turn off X display specification

Making tcsh Shell Variables Read-Only

In tcsh, a shell variable can be made read-only using set –r. A read-only variable cannot be modified with set, or removed with unset:

% set -r xyz
% set xyz
set: $xyz is read-only.
% unset xyz
unset: $xyz is read-only.

A system administrator can use read-only variables to place a non-modifiable variable in the working environment of all tcsh users. At a busy site where terminal lines and other resources are at a premium, the following line can be placed in a system-wide startup file to log out idle users after an hour of inactivity:

set -r autologout = 60            Log out idle users after 60 minutes

Paired Variables

Some shell variables have a corresponding environment variable, so that setting one member of the pair implicitly sets the other. For instance, you can use either of the following commands to specify your terminal type:

set term = vt100                This also sets the TERM environment variable
setenv TERM vt100               This also sets the term shell variable

path and PATH are another such pair, although their values are specified using different formats:

set path = (˜/bin /usr/bin /bin /usr/ucb)
setenv PATH /usr/staff/dubois/bin:/usr/bin:/bin:/usr/ucb

When you set either path or PATH, the shell automatically converts the value to the format required by the other.

Organizing Your Startup Files

You need to choose which of the two startup files you want to put given commands in. When I suggest an addition to a startup file in this handbook, I indicate the preferred file to minimize confusion. If you’re making your own additions, consider the issues below when deciding where a command belongs.

You may discover that a little rearrangement of your startup files is in order even if you’ve never altered them. The boilerplate startup files that vendors ship for use in creating new accounts often have commands in the wrong file. For instance, the history and prompt variables are sometimes set in .login, rather than in .cshrc.

Login Versus Non-Login Shells

The shell you get when you log in is (naturally) a login shell, and it reads both .cshrc and .login. There are also non-login shells, such as those that execute commands implemented as csh scripts, or those that execute !command shell escapes from programs like mail, more, or vi. Non-login shells read only .cshrc.

Consequently, if a command must be run for each shell that starts up, the command should usually appear in .cshrc. Commands that need to be run only at login should appear in .login. Examples of the latter include:

  • Commands that affect your terminal settings, like tset, reset, and stty.

  • Commands that set environment variables. (Non-login shells inherit environment variables from the login shell, so you need to set those variables only once, using .login, not .cshrc.)

  • Commands like biff, which controls the announcement of new mail, or mesg, which determines whether other users can write to your terminal.

  • Commands that produce output. For instance, some people like to execute uptime at login time to find out how busy the system is, msgs –q to see if there are new system messages, who to see who else is logged in, or date to display the current date and time.

Interactive Versus Non-Interactive Shells

A shell can be interactive or non-interactive. An interactive shell interacts with a user, who types commands. A non-interactive shell receives input from another source, such as a script file.

Interactive and non-interactive shells have somewhat different capabilities and behaviors. For example, only interactive shells print a prompt or allow you to use job control and command history. Commands that apply only to interactive shells can be skipped, reducing start up time:

if ($?prompt) then
    set prompt = "% "
    set notify
    set history = 20
    set ignoreeof

The if-statement tests whether the prompt variable has a value, to distinguish between interactive and non-interactive shells.[5] This test works because interactive shells give prompt a default value before reading any startup files, and non-interactive shells do not. Commands that are relevant only to interactive shells can be placed between the if and the endif, and non-interactive shells will ignore them.

Don’t set your prompt until after you check its default value. If you include a set prompt command in your .cshrc file before the if-statement that tests whether the prompt is set, the test will always succeed whether or not the shell is interactive!

Using the source Command

If you put a lot of stuff in your startup files, they can get pretty long. One way to reduce clutter is to group similar commands into separate files, and then reference them using the source command. For example, you might put your aliases and command editor key bindings in the files .aliases and .bindings, in your home directory. You could then refer to the files in .cshrc, like this:

source ˜/.aliases               Process alias definitions
source ˜/.bindings              Process key bindings

Another advantage to this approach is that if you change one of the individual files, you can source it without having to reprocess your entire .cshrc file.

Protecting tcsh-Only Commands from csh

Even if tcsh is your login shell, csh may read your .cshrc file occasionally. Some programs are implemented as csh scripts, so .cshrc might be read when csh is invoked to execute the script. Therefore, you need to be careful about putting tcsh-specific commands in your .cshrc file. An error will occur if csh tries to execute tcsh commands like bindkey or complete.

You can avoid problems by using the following construct to protect tcsh-specific commands from csh. It relies on the fact that tcsh sets the tcsh variable before it reads any startup files and csh does not. The result is that tcsh executes the conditional block and csh ignores it:

if ($?tcsh) then
    bindkey -e
    complete cd 'p/1/d/'

Another approach is to use .tcshrc for tcsh, and .cshrc for csh. A simple way to create .tcshrc is to copy .cshrc and add any tcsh-specific commands. However, later changes may need to be made to both files. As an alternative, you can create a version of .tcshrc that, in effect, executes all the commands in .cshrc, and then executes certain tcsh-specific commands, too. The layout shown below accomplishes this task:

source ˜/.cshrc                   Get all the usual csh stuff from .cshrc
bindkey -e                        Now do tcsh-specific stuff
complete cd 'p/1/d/'

The .logout File

If a .logout file exists in your home directory, the shell reads it when you log out. This file can be used to hold commands you want to execute when you’re done working — like clear, to clear the screen.

.logout is not processed if you use the login command to log in again, without logging out first.

[5] The space after the if should be included. Some versions of csh fail if it’s not there.

Get Using csh & tcsh now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.