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
    .
    .
    .
endif

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/'
    .
    .
    .
endif

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/'
.
.
.


[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 books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.