Unix Power ToolsUnix Power ToolsSearch this book

3.3. Shell Setup Files -- Which, Where, and Why

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.

System-wide setup
Your login(1) command probably sets some environment variables ( Section 35.3) like HOME, PATH, SHELL, TERM, MAIL, and LOGNAME or USER; check its manual page. Your system may set some environment variables or other parameters that apply to all shells or to all shells of a particular type (all bash shells, zsh shells, etc.). All of these will be passed through the environment, from parent process to child process (Section 35.4), to all of your shells, login and nonlogin.

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

Bourne shell
The original Bourne shell has one file that it reads when you log in: it's called .profile and is in your home directory. Put all your setup commands there. Later versions of the Bourne shell may also read /etc/profile before your local setup file is read and may also read the contents of whatever file is named in the ENV environment variable (Section 35.3) (but only for interactive shells). You may set this variable from your own .profile:

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.

C shell
C shell users have several shell setup files available:

Korn shell
The Korn shell is a lot like the Bourne shell. A login Korn shell (Section 3.4) will read the .profile first; recent versions do so only after reading /etc/profile, if present. The .profile can set the ENV (Section 35.5) environment variable to the pathname of a file (typically $HOME/.kshrc). Any child Korn shell started by that login shell -- including all subshells -- will read the file named by $ENV as it starts up, before printing a prompt or running other commands.

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
bash is something of a cross between the Bourne and C shells. A login bash will read .bash_profile , .bash_login, or .profile. A noninteractive bash will read a file named .bashrc in your home directory. The shell reads .bash_logout when you end a login shell; you can set a trap (Section 4.18) to handle nonlogin shells.

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.

tcsh
tcsh is like the C shell but more flexible. If a tcsh shell is run, it first tries to read .tcshrc and, if not found, then tries .cshrc. In addition, tcsh will also load either .history or the value of the histfile variable, if set; then it may try to read .cshdirs or the value of the dirsfile variable.

zsh
As always, zsh is very flexible. Startup files are read from the directory named in the ZDOTDIR environment variable, if any;[6] otherwise, from HOME. All shells read the global /etc/zshenv and your .zshenv files. If the shell is a login shell, commands are read from /etc/zprofile and then your .zprofile. Then, if the shell is interactive, commands are read from /etc/zshrc and your .zshrc. Finally, if the shell is a login shell, /etc/zlogin and your .zlogin files are read.

[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



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.