To understand setup files, you need to understand that a shell can act like a login shell or a nonlogin shell (Section 3.4). There are different setup files for nonlogin and login shells.
When you log in to a Unix system -- but not under a window system -- the login program starts a shell for you. The login program sets a special flag (Section 3.19) to tell a shell that it's a login shell. If the shell doesn't have that flag set, it won't act like a login shell. Opening a new window in a window system may or may not set the "login shell" flag -- that depends on the configuration. (For example, the command xterm -ls starts a login shell in an xterm window (Section 24.20); xterm +ls starts a nonlogin shell.) When you connect to a system with programs like ftp and scp, that usually starts a nonlogin shell. And a subshell (Section 24.4) is never a login shell (unless you set a command-line option to force a login shell, like bash -l).
How can you tell whether your shell is a login shell? The answer is "it depends." When you first log in to a system, you want a login shell that sets things like the terminal type (Section 5.2, Section 5.3). Other shells on the same terminal should be nonlogin shells -- to avoid redoing those one-time-only setup commands. Different shells have their own methods for handling first-time shell invocations versus later invocations, and that's what the rest of this article is about.
Parenthesis operators (Section 43.7) don't read any setup file. Instead, they start another instance of your current shell. Parentheses are called "subshell operators," but the subshell they start doesn't print a prompt and usually has a short lifetime.
Next, let's look at the setup files -- login and nonlogin -- for the major shells. I recommend that you read about all of them. Then experiment with your shell's setup files until you get things working the way you want them.
Once login or your window system starts your individual shell, it may also read its own system-wide setup files. These files, if any, will be read before your personal setup files. Check your shell's manual page and the /etc directory for files like csh.login, bashrc, zshrc, and so on. On Red Hat systems, for example, there is a directory named /etc/profile.d containing package-specific C and Bash shell config files that are sourced (read into the current shell) on startup of a shell. On Mac OS X, when you use Terminal (Section 3.2), your shell (which is tcsh by default) reads /private/etc/csh.cshrc, as well as any user-specific files (e.g., ~/.tcshrc).
ENV=$HOME/.mystartup; export ENV
The Bourne shell doesn't read .profile when you start a nonlogin shell or subshell (Section 43.7), though. Subshells are set up through inheritance of environment variables (Section 35.3) that were set when you first logged in (in system-wide setup files or .profile) or from commands you typed since.
The .cshrc file is read any time a C shell starts -- that includes shell escapes and shell scripts.[4] This is the place to put commands that should run every time you start a shell. For instance, shell variables like cdpath (Section 31.5) and prompt should be set here. Aliases (Section 29.2) should, too. Those things aren't passed to subshells through the environment, so they belong in .cshrc (or .tcshrc). See the upcoming section on tcsh for more details.
[4]If you write a csh (or tcsh) script, you probably should use the -f option to keep scripts from reading .cshrc (or .tcshrc). However, you probably shouldn't use csh or tcsh for scripts.
Alternately, you can put aliases into a separate file and use the source command to read the file into the current shell from your .cshrc/.tcshrc -- if you're the sort who likes to have custom init files for every host you log in to, but like your aliases to be common wherever you go. This provides a quick and easy way for you to copy your .csh.aliases (or whatever name you give it, being careful to distinguish between it and the slightly different format required by bash aliases) from host to host without clobbering your custom, localized init files.
When csh starts up, on recent systems it may read a system-wide setup file, such as /etc/csh.cshrc,[5] and for login shells, /etc/csh.login.
[5]On Mac OS X, /etc is a symbolic link to /private/etc. The actual initialization files for tcsh are in /usr/share/init/tcsh.
Your .login file is read when you start a login shell. You should set several things here. Set environment variables (Section 35.3) (which Unix will pass to subshells automatically). Run commands like tset (Section 5.3) and stty (Section 5.7, Section 5.8) that set up your terminal. Finally, include commands you want to run every time you log in -- checking for mail and news (Section 1.21), running fortune, checking your calendar for the day, etc.
Note that .cshrc is read before .login, by csh, but that tcsh may be compiled such that the order is reversed, and .tcshrc may be read after .login in some environments. Check the version shell variable to find out how your environment is set up.
The shell reads .logout when you end a login shell. Section 3.8 has tips for reading .logout from nonlogin shells.
The public domain Korn shell often found on Linux may also be further restricted when invoked as a "privileged" shell, using a pattern that matches r*sh, in which case neither the ~/.profile nor the file named by the ENV environment variable will be read. Instead, the shell will be initialized using /etc/suid_profile, if present.
bash also uses GNU Readline for reading and editing text you enter at a shell prompt. The .inputrc file configures Readline for a given user; /etc/inputrc is for global configuration.
[6]ZDOTDIR may be hard to set on your first login -- when your zsh is a login shell -- because it's hard to set an environment variable before your first shell starts. (The system program that starts your shell, like login(1), could do the job, I guess.)
--JP and SJC
Copyright © 2003 O'Reilly & Associates. All rights reserved.