Donation?

Harley Hahn
Home Page

Send a Message
to Harley


A Personal Note
from Harley Hahn

Unix Book
Home Page

SEARCH

List of Chapters

Table of Contents

List of Figures

Chapters...
   1   2   3
   4   5   6
   7   8   9
  10  11  12
  13  14  15
  16  17  18
  19  20  21
  22  23  24
  25  26

Glossary

Appendixes...
  A  B  C
  D  E  F
  G  H

Command
Summary...

• Alphabetical
• By category

Unix-Linux
Timeline

Internet
Resources

Errors and
Corrections

Endorsements


INSTRUCTOR
AND STUDENT
MATERIAL...

Home Page
& Overview

Exercises
& Answers

The Unix Model
Curriculum &
Course Outlines

PowerPoint Files
for Teachers

Chapter 14...

Using the Shell:
Initialization Files

This is the last of four chapters that deal with the shell. Chapter 11 discussed the shell in general; Chapter 12 and 13 covered the basic concepts needed to use the shell well.

In this chapter, we will discuss the last major topic, initialization files. You will like this chapter because, as you read it, everything you have already learned will come together. As it does, you will begin to appreciate the beauty of the shell.

Jump to top of page

Initialization Files and Logout Files

The Unix shells were designed by programmers who knew the value of letting users customize their working environments. Toward this end, all shells allow you to specify commands to be executed automatically on your behalf. Your job is to use these commands to set up your working environment exactly how you want it. Here is how it works.

To start, you create two special files, called INITIALIZATION FILES. In the first file, the LOGIN FILE, you put all the commands you want executed every time you log in. In the second file, the ENVIRONMENT FILE, you put the commands you want executed every time a new shell starts.

For example, you might use your login file to set specific variables each time you login. If you use a multiuser system, you might also run the users command to show you who else is logged in. And you might use your environment file to set specific shell options and define certain aliases every time a new shell starts.

Once you create your initialization files, the shell will look for them and run the commands automatically at the appropriate times. If your needs change, just change the files.

To provide a bit more customization, some shells also support a LOGOUT FILE. The logout file holds commands that are run automatically whenever you log out. For example, you might run the date command whenever you log out, to display the current time and date.

— hint —

In the olden days, there was a cool program named fortune. Each time you ran the program it would display a joke or pithy saying, selected at random from a large collection of interesting diversions. Many people put a fortune command in their logout file, so they would see something interesting each time they logged out.

Unfortunately, the fortune command is not included with most of today's Unix/Linux systems. However, it is readily available on the Net, and you might want to download and install it. If you do, you will find that fortune is an excellent command to put in your logout file.

Taken together, the login file, environment file, and logout file give you the power to cause any commands you want to be executed automatically at three different times: when you log in, whenever a new shell starts, and when you log out.

Can you see the elegance of this design? The ability to run commands at these three specific times gives you the control you need to set up your work environment exactly the way you want. If you are a beginner, the power of these files will not be obvious. However, once you have used Unix for a year or two, and you become good at setting variables, creating shell scripts, and defining aliases and functions, you will appreciate how important the initialization files are to your overall Unix experience. (We talked about aliases in Chapter 13; functions are beyond the scope of the book.)

The names of the three different files differ from one shell to another. For example, with the C-Shell, the login file is called .login; the environment file is .cshrc; and the termination file is .logout. Figure 14-1 shows the standard names used with the various shells. Look closely and you will see that the Bourne shell family (Bash, Korn shell) uses a different pattern of filenames than the C-Shell family (C-Shell, Tcsh).

You will notice that all the initialization and logout files have names that begin with a . (dot) character. Such files are called "dotfiles", and we will discuss them later in the chapter and again in Chapter 24. For now, you only need to know three things. First, a dot (that is, a period) is a legitimate character in a filename. Second, a dot at the beginning of a name has a special meaning. Third, when you talk about a dotfile, you pronounce the "dot". For example, when you talk about the .login file, you say "dot-login"; when you talk about .profile, you say "dot-profile".

Figure 14-1: Names of the initialization and logout files

Unix shells allow you to customize your working environment by placing commands in special files that are run automatically at certain times. There are two initialization files, the login file (run when you log in) and the environment file (run whenever a new shell starts). Some shells also allow you to use a logout file (run when you log out). As you can see from the table, the names of these files vary from one shell to another. The original Bourne shell, which I included for interest, used only a login file called .profile.

Notes: (1) The Korn shell and Bash (in POSIX mode), do not use a standard name for the environment file. Instead, you set the ENV variable to the name of whichever file you want to use. (2) If your shell does not support a logout file, it is still possible to use one by trapping the EXIT signal. (See text for details.)

Shell Login File Environment File Logout File    
C-Shell.login.cshrc.logout
Tcsh.login.tcshrc, .cshrc.logout
Bourne Shell.profile
Korn Shell.profile$ENV
Bash (default mode).bash_profile, .bash_login.bashrc.bash_logout
Bash (POSIX mode).profile$ENV.bash_logout

Jump to top of page

Names of Initialization and Logout Files

The names used by the C-Shell family for initialization and logout files are straightforward. The login file is .login; the environment file is .cshrc for the C-Shell and .tcshrc for the Tcsh; and the logout file is .logout. For backwards compatibility, if the Tcsh can't find a file named .tcshrc, it will look for one named .cshrc, which only makes sense.

The names used by the Bourne shell family take a bit of explanation. To start, we need to recall an important idea from Chapter 11. In the early 1990s, a set of specifications called POSIX 1003.2 was created to describe a "standard" Unix shell. For the most part, the POSIX standard was modeled after the Bourne shell family. Indeed, today's modern Bourne shells (Bash, Korn shell, FreeBSD shell) all conform to the 1003.2 standard.

The POSIX standard mandates that a shell should support both a login file and an environment file, but not necessarily a logout file. The name of the login file should be .profile. However, to retain flexibility, the name of the environment file is not fixed. Instead, an environment variable named ENV should hold the name of the environment file. For example, if you are a Korn shell user, you might set the value of ENV to .kshrc. (We'll talk about filenames later.)

If you look at Figure 14-1, you will see that the Korn shell follows the POSIX specification: The name of the login file is .profile, and the name of the environment file is stored in the ENV variable.

Bash is different because it was created by very clever programmers (see Chapter 11) who designed it to run in two different modes: default mode, for power and flexibility(*), and POSIX mode for compatibility. In default mode, Bash supports enhancements over the POSIX standard; in POSIX mode, Bash strictly adheres to the 1003.2 standard.

* Footnote

Of all the major shells, the only one that offers more flexibility than Bash is the Zsh (see Chapter 11).

In general, the Bash default mode is just fine, and that is what most people use most of the time. However, if you ever have a need for a POSIX-compliant shell, say, to run a special shell script, you can always run Bash in POSIX mode(*).

* Footnote

There are two ways to run Bash in POSIX mode. First, you can start it with the --posix option. This technique will work on all systems:

bash --posix

The second choice is simpler, but only works on some systems.

Some Unix systems are set up so that both the bash command and the sh command will start Bash. (This is generally the case with Linux.) On such systems, the bash command starts the shell in default mode, while the sh command starts the shell in POSIX mode.

In default mode — which is what you and I would normally use — Bash looks for a login file named either .bash_profile or .bash_login (use whichever one you want), and an environment file named .bashrc.

In POSIX mode, Bash follows the same rules as the Korn shell. The login file is named .profile, and the name of the environment file is stored in the ENV variable.

In both modes — the default mode and the POSIX mode — Bash uses a logout file named .bash_logout.

You should now be able to understand all of Figure 14-1, which means we can turn our attention to a very important question: What types of commands should you put in your initialization files and in your logout file?

Before I lay the groundwork for answering that question, I want to make two quick digressions, one to explain about dotfiles and rc files, the other to talk about what you need to know in order to create and edit a file.

Jump to top of page

Dotfiles and rc Files

When you look at the filenames in Figure 14-1, you will notice two odd things. First, all the names begin with a dot; second, the names of the environment files end with rc.

Files whose names start with a period are called DOTFILES or HIDDEN FILES. We will discuss them in Chapter 24 but, to help you now, here is a summary in advance.

There are many files that, for one reason or another, you want to ignore most of the time. Usually, these are configuration files that are used silently by some program or other. A good example of this are the shell initialization files we have been discussing.

As we will discuss in Chapter 24, the command you use to list your files is ls. As a convenience, ls will not list any names that begin with a dot unless you use the -a (all files) option. Thus, when you use ls in the usual manner, you won't see the names of any of your dotfiles.

This is why all the initialization and logout files have names that begin with a dot. Once you set up the files the way you want, there is no reason to think about them unless you want to make a change. In particular, you don't want to look at their names every time you list your files.

If you ever do want to list all your files, including the dotfiles, just use ls -a. To see how it works, take a moment to try both commands:

ls
ls -a

Moving on, you will notice that the environment files have names that end with the letters rc: .bashrc, .cshrc and .tcshrc. This is a common convention used by Unix programs for naming initialization files. For example, the vi and ex editors (which are related) use an initialization file named .exrc; and the generic Unix email program, mail, uses an initialization file called .mailrc.

As you work with Unix over the years, you will encounter a great many rc files. As a general rule, such files are used to hold initialization commands and, almost always, they will be dotfiles to hide them from the ls command.

What's in a Name?

rc Files


Many Unix programs use configuration files whose names end in rc, for example, .bashrc, .tcshrc and .exrc. The designation rc stands for "run commands": commands that are run automatically each time a particular program starts.

The name derives from the CTSS operating system (Compatible Time Sharing System), developed at MIT in 1963. CTSS had a facility called "runcom" that would execute a list of commands stored in a file. Some of the early Unix programmers had used CTSS and, when they created configuration files, they chose names that ended in rc.

This was the start of a long-standing tradition among Unix programmers of naming initialization files by using dotfiles whose names end in rc. For example, if you wrote a program called foo, you would probably name the initialization file .foorc. That is why, earlier in the chapter, I suggested that, if you are a Korn shell user, you should name your environment file .kshrc.

When we talk about such files, we pronounce rc as two separate letters. For example, .foorc is "dot-foo-R-C". For reference, Figure 14-2 shows the pronunciations for the most common environment files. Knowing how to pronounce such names is important when you talk to other Unix people.

Figure 14-2: Pronouncing the names of rc files

Many Unix programs use initialization files whose names start with a dot (period) and end with the letters rc. The dot keeps the names from being displayed when you list your files; the rc is a abbreviation for "run commands". (See text for a full explanation.) This table lists the names of the most common shell environment files, along with the most common pronunciation for each name. Can you see the pattern?

Environment File  Pronunciation
.cshrc"dot-C-shell-R-C"
.tcshrc"dot-T-C-shell-R-C"
.bashrc"dot-bash-R-C"

Jump to top of page

Using a Simple Text Editor

In order to be a skillful Unix user, you must be able to edit (modify) text quickly. This is especially true if you are a programmer. Specifically, your login file, environment file, and logout file all contain text and, in order to create or modify these files, you need to be able to use a text editor program.

The two main Unix text editors are vi and Emacs and, eventually, you will need to master one of them. However, both vi and Emacs are complex. In fact, within this book, I have devoted an entire chapter to vi (Chapter 22). Reading this chapter, or teaching yourself Emacs, will take some time, so I have some alternatives for you. If you use a desktop environment such as Gnome or KDE (see Chapter 5), there will be a simple GUI-based editor you can use to create and modify small text files. If you use the CLI (command line interface), there will probably be a simple text-based editor you can use until you learn vi or Emacs.

Let's start with the desktop environment. There are two ways to access the GUI-based editor. First, you can start it from within the menu system. You will most likely find it listed under "Accessories". Second, you can start the program from a command line. Just open a terminal window (see Chapter 6), wait for the shell prompt, and enter the name of the program. With KDE, the GUI-based text editor is kedit; with Gnome, it is gedit.

Most Linux systems will have KDE or Gnome, but even if you don't use Linux, try running gedit anyway. It's part of the GNU utilities (Chapter 2) and, as such, you will find it on many different systems. For example, you can run gedit from a Solaris terminal window under JDS (the Java Desktop System).

If you don't have access to a GUI-based editor, there is a good chance your system will have a simple text-based editor. The most common ones are Pico and Nano. (They are pretty much the same; Nano is the GNU version of Pico.) To check if your system has one of these editors, see if you can display one of the man pages. If so, you can use the man page to teach yourself the basics:

man pico
man nano

Once you figure out how to use one of the simple text editors — either a GUI-based text editor or Nano/Pico — you can use it to create and edit your initialization and logout files. However, remember what I said: such programs are only for beginners. In the long run, you need to learn either vi or Emacs.

Jump to top of page

Login Shells and Non-Login Shells

In Chapter 12, we talked about interactive and non-interactive shells. You use an interactive shell when you enter commands at the shell prompt; you use a non-interactive shell when you run a shell script. In order to understand how to use initialization files, we need to go a bit further in our analysis, because there are two different types of interactive shells.

Whenever you log in, the shell that starts is called a LOGIN SHELL. All other interactive shells are called NON-LOGIN SHELLS. The distinction is important because initialization files are processed differently for login shells than for non-login shells. Let's consider a few common situations.

1. Virtual consoles and terminal windows

When you use a desktop environment, such as Gnome or KDE, there are two ways to get to a shell prompt: you can open a terminal window, or you can change to a virtual console (see Chapter 6). When you use a virtual console — say, by pressing <Ctrl-Alt-F1> — you are required to log in. When you do, a login shell starts. On the other hand, if you simply open a terminal window, a non-login shell starts (because you did not log in).

2. Starting a new shell

At any time, you can start a new shell by entering its name. For example, say you are using Bash, and you want to try the Tcsh. Just enter the tcsh command. The new shell is a non-login shell (because you did not log in).

3. Using a remote host

To connect to a remote Unix host, you use the ssh (Secure Shell) program. Once ssh makes the connection for you, you must log in. Doing so starts a login shell.

Jump to top of page

When Are Initialization Files Executed?

Now that you understand the difference between a login shell and a non-login shell, we can discuss what happens when a new shell starts. The important question to answer is: Which initialization files are executed and when?

There are two general rules, with minor variations. Let's start with the rules.

1. A login shell executes your login file and your environment file.

2. A non-login shell only executes your environment file.

Here are the specific details, starting with the members of the Bourne shell family. As a shortcut, I will use $ENV to represent the file whose name is stored in the $ENV environment variable. For example, for the Korn shell, you might set the value of $ENV to be .kshrc.

Bash (default mode)
• Login shell: .bash_profile
• Non-login shell: .bashrc

Bash (POSIX mode)
• Login shell: .profile, then $ENV
• Non-login shell: $ENV

Korn shell
• Login shell: .profile, then $ENV
• Non-login shell: $ENV

Before we move on to the C-Shell family, let me make a few comments. First, you will notice that we can divide all the Bourne shells into two groups. Two of the three shells follow the POSIX convention of using .profile and $ENV. The exception is Bash in default mode. This is an important insight because, once you have used shells for a while, you will see that there is something different about Bash.

Bash reflects the attitudes of the young programmers who came of age in the mid- to late 1990s, during the growth of Linux and the open source movement (see Chapter 2). Emotionally, the open source programmers felt a bit like outlaws, rebelling against commercial Unix conventions, such as proprietary software and restrictive licensing agreements. For this reason, they opted to create an enhanced shell that was more than just a clone of the standard POSIX shell(*). This is why, as a Bash user, you will encounter many situations in which Bash behaves differently than other shells.

* Footnote

To be sure, the Bash programmers were not complete iconoclasts. They did create POSIX mode for situations that require strict conformity to community standards.

For example, it is only the Bash login shell that executes a login file and not an environment file. With all other shells, a login shell executes both the login file and the environment file, in that order. This means that Bash users must put a special command in their login file to force it to execute the environment file. (I'll show you how to do this.)

Moving on, let's take a look at how the members of the C-Shell family use initialization files:

C-Shell
• Login shell: .cshrc, then .login
• Non-login shell: .cshrc

Tcsh
• Login shell: .tcshrc, then .login
• Non-login shell: .tcshrc

(For backwards compatibility, if the Tcsh can't find .tcshrc, it will look for .cshrc.)

This pattern is straightforward, except for one interesting anomaly. In the C-Shell family, login shells execute the environment file first. In the Bourne shell family, login shells execute the login file first. To understand why this is the case, we need to talk a bit about the history of initialization files.

Jump to top of page

A Quick History of Shell Initialization Files

(In this section, I am going to talk a bit about the history of the shell. For more details, see Chapter 11.)

The original Unix shell was written by Ken Thompson and used at Bell Labs in the early 1970s. This shell did not make use of a standardized initialization file. In the mid-1970s, Bell Labs programmers wrote two new replacement shells: the Mashey shell (also known as the PMB shell) and the Bourne shell. A programmer named Dick Haight added support for an initialization file (.profile) to the Mashey shell. Later, the same feature was added to the Bourne shell.

The .profile file was executed only once, when you logged in. In 1987, when Bill Joy developed the C-Shell at U.C. Berkeley, he enhanced the initialization process by using two files instead of one. The first file, .cshrc, ran every time a new shell started. The second file, .login, ran only when a login shell started. Thus, it made sense to execute .login after .cshrc, as its job was to run only those extra commands that were necessary at login time.

In 1982, David Korn of Bell Labs developed another replacement for the Bourne shell, the Korn shell. Korn adopted Bill Joy's idea of using two initialization files, what we now call an environment file (.cshrc) and a login file (.login). Because Korn worked at Bell Labs, which was a Bourne shell shop, he used the name .profile for the login shell. When it came time to the name the environment file, Korn decided to let the users choose the name for themselves, by setting the ENV variable to the name of the environment shell. In this way, you could have more than one environment file for different purposes.

However, once he made this decision, Korn had to ensure that the login file executed before the environment file. Otherwise, there would be no way for a user to set the ENV variable.

That is why, to this day, Bourne family shells run the login file first, and the C-Shell family shells run the environment file first. In practice, this is usually not a big deal, but it is something to remember if you ever have a mysterious initialization problem that seems insolvable.

Jump to top of page

What to Put in Your Initialization Files

We can now consider the questions I posed a while back: What should you put in your login file? What should you put in your environment file? Here are the answers.

Your login file has two jobs: to set up your environment and to initialize your work session. Thus, your login file should contain commands to (1) create or modify environment variables, and (2) perform all one-time actions.

The login file, then, is where you set variables such as PATH, PAGER, and so on, and use umask to set your file creation mask (Chapter 25). If the login file is for a remote host, you may also need to use stty to modify key mappings (Chapter 7). Finally, you may want to display a personal message or other information each time you log in.

As we discussed earlier in the chapter, the environment is automatically inherited by all child processes, including new shells. Thus, you only need to set environment variables (such as PATH) once, in your login file. It makes no sense to set an environment variable in your environment file, where it will be reset every time a new shell starts.

Your environment file has a different job: to set up whatever customizations cannot be stored in the environment, in particular, shell options, aliases and functions. Because these settings are not stored in the environment, they must be recreated every time a new shell starts.

Jump to top of page

Displaying, Creating and Editing
Your Initialization Files

You may already have one or more initialization files. On a shared system, such files are often created by the system administrator. On your own system, they may be generated automatically at the time your account was created. If you already have such files, you can modify them to suit your needs. If not, you can create the files yourself.

Initialization files are kept in your home directory (your personal directory; see Chapter 23). As we discussed earlier, all initialization files are dotfiles, which means their names start with a . (period). For reference, Figure 14-1, earlier in the chapter, contains the names of the standard initialization files.

As we discussed earlier, you display the names of all your dotfiles by using the the ls -a command. (Without the -a option, ls won't show dotfiles.) If the list is too long, you can send it to less:

ls -a
ls -a | less

Once you see which initialization files you have, you can look at their contents by using less. One of the following commands should do the job:

less .bash_login
less .bash_logout
less .bash_profile
less .bashrc
less .cshrc
less .kshrc
less .login
less .logout
less .profile
less .tcshrc

To create or modify a dotfile, you need to use a text editor. If you already know vi or Emacs, great. If not, you can — for now — use one of the simpler editors we discussed earlier, kedit or gedit. Because these are GUI-based editors, you must use them from within a desktop manager. You can't use them from a virtual terminal or from a CLI connected to a remote host.

Starting from your GUI, open a terminal window and enter the the name of the editor, followed by the name of the file you want to create or edit. With KDE, use kedit; with Gnome, use gedit. For example:

kedit .bash_login
gedit .bash_login

A new window will open. If the file already exists, it will be loaded, allowing you to modify the contents. If the file does not exist, you will have an empty window, allowing you to create the file.

Jump to top of page

Comments in Shell Scripts

The initialization files we have been discussing are actually shells scripts: programs that are written in the language of the shell and executed by the shell. In a moment, we will take a look at some sample scripts. Before we do, I want to explain an important point regarding shell scripts and programs in general.

Take a look at the initialization files in Figure 14-3, 14-4, 14-5 and 14-6. Although they are quite different from one another, you will notice they have one thing in common: many of the lines begin with a # (hash or pound) character. Such lines are called COMMENTS.

As a script is executed, the shell ignores all the comments. This allows you to put in notes to help you remember the logic and understand the script. If you have never programmed before, you might think comments should not be necessary when you write scripts for your own use. Surely, when you read a script at a future date, you will remember the logic behind the various commands. After all, you are the one who wrote the script in the first place.

The truth is, although your reasoning may be clear right now, when you read a shell script, or any program, even a few days later, you will have trouble remembering what you were thinking at the time. This is why all experienced programmers put lots of comments in everything they write.

Moreover, the time may come when someone else will need to read your scripts. In such cases, comments are invaluable. My advice is to document what you are doing, as you are doing it. Pretend that everything you write will have to be understood by another person. Later, you will be that person and, believe me, you will never be sorry you took the time to put in comments(*).

* Footnote

When I was a computer science grad student at the University of California at San Diego, I was a teaching assistant for a course in systems programming, a very technical type of programming. At the same time, there was another teaching assistant named Peter.

Although Peter and I got along, there was one point on which we disagreed categorically. I felt we should teach the students to use lots of comments in their programs. Peter didn't like comments, and he didn't teach his students to use them. He said the comments got in the way of his reading the programs (which we had to grade).

After graduating, I went on to medical school and became a professional writer. To date, I have written 32 books which have sold over 2,000,000 copies and been translated into many languages. I live in Southern California with a beautiful, intelligent woman, in a house with an ocean view. We have loving families and we share wonderful friends and a variety of interests and accomplishments. Peter, on the other hand, most likely turned out to be a total failure.

The moral, I think, is obvious.

Within a shell script, the actual definition of a comment is a # character and everything the follows it to the end of the line. Thus, a comment can take up all or part of a line. Consider the following example:

# Display the time, date, and current users
date; users

The first line is a comment; the second line contains two commands with no comments. When the shell executes these two lines, it will ignore the comment and run the commands on the second line. Now consider:

date; users # Display time, date, and current users

In this case, we have a single line, containing two commands followed by a comment. When the shell executes this line, it will run the date command and users command, and ignore everything else on the line. Thus, when you write shell scripts, you have two ways to put in a comment: at the end of a line, or on a line by itself.

In the following few sections, we will take a closer look at the sample initialization files. As we do, think about how difficult it would be to understand these files if there were no comments.

Jump to top of page

Bourne Shell Family:
Sample Initialization Files

In the next two sections, we will discuss four sample initialization files. What you are about to see will tie together everything you have learned in the last three chapters: interactive shells, environment variables, shell variables, shell options, metacharacters, quoting, the search path, command substitution, the history list, command line editing, aliases, and comments. My intention is for you to adapt these files for your own use, making whatever changes and additions are necessary to serve your needs.

In this section, we will discuss initialization files that are suitable for a member of the Bourne shell family (Bash, Korn shell). In the next section, we will discuss initialization files for the C-Shell family. Regardless of which shell you happen to use right now, I'd like you to take a look at both sections. Over the course of your life with Unix and Linux, you will find yourself using a variety of systems, and it will help you to be familiar with the initialization files for both shell families.

Our goal in this section is to take a close look at a sample login file and a sample environment file. You will find the login file in Figure 14-3. I will remind you that this is the file that is executed automatically each time you log in. With Bash, your login file will be named .bash_profile or .bash_login. With the Korn shell, or Bash in POSIX mode, it will be .profile.

The environment file is in Figure 14-4. This file is executed every time a new shell starts. With Bash, your environment file is named .bashrc. With the Korn shell or Bash in POSIX mode, you can name the environment file anything you want by setting the ENV variable. My suggestion is to use .kshrc for the Korn shell and .bashrc for Bash.

With the Bourne shell family, the login file is run first, before the environment file, so we will discuss the login file first. (With the C-Shell family, the environment file is run first.)

Figure 14-3: Bourne shell family: Sample login file

The login file is executed automatically each time you log in. Here is a sample login file suitable for Bash or the Korn shell. Use this file as a template and adapt it for your own use. See text for details.

# ======================================
# Bourne shell family: Sample login file
# ======================================

# 1. Environment variables
export HISTSIZE=50
export PAGER=less
export PATH="${PATH}:${HOME}/bin"
export VISUAL=vi

# 2A. Shell prompt - Bash
export PS1="(\w) `basename ${SHELL}`[\!]$ "

# 2B. Shell prompt - Korn shell
export PS1="(\$PWD) `basename ${SHELL}`[!]$ "

# 3. File creation mask
umask 077

# 4. Terminal settings (for remote host only)
stty erase ^H
# stty erase ^?

# 5. Display welcome message
echo "Welcome Harley."
echo "Today is `date`."
echo

# 6. System information
echo "Last three logins:"; last `logname` | head -3
echo
echo "Current users: `users`"
echo
echo "System uptime:"; uptime
echo

# 7A. Environment file - Bash
if [ -f ${HOME}/.bashrc ]
then source ${HOME}/.bashrc
fi

# 7B. Environment file - Korn shell
export ENV=${HOME}/.kshrc

# 8. Logout file - Korn shell
trap '. ${HOME}/.logout; exit' EXIT

By now, you should understand most of the commands, variables and options used in the sample files. I'll go over each section for you and, for reference, I'll tell you the chapter in which you can find more information should you need it.

Section 1 of the login file defines the environment variables. We set the size of the history list to 50 lines, the default paging program to less, and the default text editor to vi. We also add a specific directory to the end of the search path. (Chapter 12: variables; Chapter 13: history list, search path; Chapter 21: paging programs.)

Sections 2A and 2B define the shell prompt by setting the PS1 environment variable. Section 2A is for Bash; section 2B is for the Korn shell. Use either 2A or 2B, but not both. (Chapter 12: variables; Chapter 13: shell prompt.)

Section 3 sets the file creation mask to control the default permissions for newly created files (Chapter 25: file permissions, umask.)

Section 4 is used only for login files on a remote host. You do not need this section when you are using Unix or Linux on your own computer. The stty command sets the key mapping for the erase signal. I have given you two possible commands: use whichever one works best with your keyboard. (Chapter 7: erase signal, stty.)

Section 5 displays a welcome message. You can change this to whatever you want. (Chapter 8: date; Chapter 12: echo, command substitution.)

Section 6 displays interesting information about the system. (Chapter 4: last; Chapter 8: whoami, users, uptime; Chapter 12: echo, command substitution; Chapter 15: pipeline; Chapter 16: head.)

Sections 7A and 7B make sure the environment file is run. Section 7A is for Bash. It checks to see if a file named .bashrc exists. If so, it tells the shell to run the file. Section 7B is for the Korn shell. It sets the value of the ENV environment variable to the name of the environment file. Use either 7A or 7B, but not both. (Chapter 12: variables; Chapter 14: environment files.)

Section 8 is for the Korn shell only. By default, the Korn shell does not support a logout file, the file that is executed automatically each time you log out. However, you can simulate a logout file by trapping the EXIT signal, which is generated when you log out. Here, we specify that when the EXIT signal occurs, the file named .logout should be executed. (Chapter 7: trapping a signal; Chapter 14: logout files.)

With the Bourne shell family, the environment file is simpler than the login file, because the login file does most of the work. All the environment file needs to do is re-create whenever is lost when a new shell is started: shell options, aliases and functions. Take a look at Figure 14-4, where you will see a sample environment file.

Figure 14-4: Bourne shell family: Sample environment file

The environment file is executed automatically whenever a new shell starts. Here is a sample environment file suitable for Bash or the Korn shell. Use this file as a template and adapt it for your own use. See text for details.

# ============================================
# Bourne shell family: Sample environment file
# ============================================

# 1. Shell options
set -o ignoreeof
set -o emacs
set -o noclobber

# 2. Aliases
alias a=alias
alias d=date
alias del='fc -s ls=rm'
alias h=history
alias l='ls -F'
alias la='ls -a'
alias ll='ls -l'
alias r='fc -s'

#3. Functions
# functions go here

Section 1 sets the shell options. The ignoreeof option requires us to use a logout or exit command to log out. By trapping the eof signal, we keep ourselves from logging out accidentally by pressing ^D one too many times. (With Bash, you can set the IGNOREEOF environment variable instead of using the shell option.) The second shell option sets Emacs for our command line editor. Strictly speaking, you don't need to set this option, as Emacs is the default. However, I like to set it explicitly as a reminder. Finally, we set the noclobber option to protect us from accidentally deleting the contents of a file when we redirect standard output. (Chapter 7: trapping the eof signal; Chapter 12: shell options, command line editing; Chapter 15: redirecting standard output.)

Section 2 sets the aliases. They include an abbreviation for the alias and date commands; several variations of the ls command; the del alias to help us avoid deleting the wrong files; and the r and h aliases to help us use the history list. (Chapter 8: date; Chapter 12: history list, aliases; Chapter 24: ls.)

Section 3 is reserved for any shell functions we may want to define. A function allows you to create your own customized commands by writing a small program. Learning to write such programs is beyond the scope of this book. However, if do use functions, this is the place to define them.

Jump to top of page

C-Shell Family:
Sample Initialization Files

In this section, we will discuss two sample initialization files for the C-Shell family (C-Shell and Tcsh). What you are about to read here will tie together everything you have learned in the last three chapters. My intention is to explain the contents of these sample files so you can adapt them for your own use by making whatever changes and additions are necessary to serve your needs.

We'll start with the environment file in Figure 14-5. I will remind you that this is the file that is executed automatically whenever a new shell starts. With the C-Shell, this file is named .cshrc. With the Tcsh, it can be named either .tcshrc or .cshrc. After discussing the environment file, we will move on to Figure 14-6, which contains a sample login file: the file that is executed whenever you log in. With both shells, this file is named .login.

We are starting with the environment file because, in the C-Shell family, it is run first, before the login file. (With the Bourne shell family, the login file is run first.)

Figure 14-5: C-Shell family: Sample environment file

The environment file is executed automatically whenever a new shell starts. Here is a sample environment file suitable for the C-Shell or the Tcsh. Use this file as a template and adapt it for your own use. See text for details.

# =======================================
# C-Shell family: Sample environment file
# =======================================

# 1. Shell variables
set filec  # only necessary for C-Shell
set history = 50
set ignoreeof
set noclobber
set path = (${path} ${HOME}/bin)
set savehist = 30

# 2A. Shell prompt - C-Shell
set prompt = "($PWD) `basename ${SHELL}` [\!]% "
alias cd 'cd \!* && set prompt = "($PWD) `basename ${SHELL}` [\\!]% "'

# 2B. Shell prompt - Tcsh
set prompt = "`basename ${SHELL}` [\!]> "
set rprompt = "(%~)"

# 3. Aliases
alias a alias
alias d date
alias del 'rm \!ls:*'
alias h history
alias l 'ls -F'
alias la 'ls -a'
alias ll 'ls -l'

By now, you should understand most of the commands, variables and options used in the sample files. I'll go over each section for you and, for reference, I'll tell you the chapter in which you can find more information should you need it.

The job of the environment file is to recreate whatever is lost when a new shell is started: shell options, the shell prompt, and aliases.

Section 1 defines the shell variables. We set the the size of the history list, add a specific directory to the end of the search path, and turn on file completion. (With the Tcsh, file completion is turned on by default. With the C-Shell, however, it is not, so if you want filename completion, you must set the filec variable.) We also set ignoreeof to trap the eof signal. This forces us to use the logout command to log out, which keeps us from logging out accidentally by pressing ^D one too many times. We also set noclobber to protect us from accidentally deleting the contents of a file when we redirect standard output. Finally, we set savehist to save the history list when we log out. (Chapter 7: trapping the eof signal; Chapter 12: variables; Chapter 13: history list, search path, autocompletion; Chapter 15: redirecting standard output.)

Sections 2A and 2B define the shell prompt by setting the prompt shell variable. Section 2A is for the C-Shell; section 2B is for the Tcsh. Use either 2A or 2B, but not both. You will notice that the C-Shell prompt contains the name of the working directory. Because this quantity is not updated automatically, we define an alias that will reset the shell prompt whenever we use the cd (change directory) command. This is not necessary for the Tcsh. With the Tcsh, we set the right-hand prompt (rprompt) to display the name of the working directory. (Chapter 12: variables; Chapter 13: shell prompt.)

Section 3 sets the aliases. They include an abbreviation for the alias and date commands; several variations of the ls command; the del alias to help us avoid deleting the wrong files; and the r and h aliases to help us use the history list. (Chapter 8: date; Chapter 12: history list, aliases; Chapter 24: ls.)

With the C-Shell family, the login file is simpler than the environment file, because the environment file does most of the work. (This is the opposite of the Bourne shell family.) Take a look at Figure 14-6, where you will see a sample login file.

Figure 14-6: C-Shell family: Sample login file

This is the last paragraph of the caption. This is the last paragraph of the caption. This is the last paragraph of the caption. This is the last paragraph of the caption. This is the last paragraph of the caption. This is the last paragraph of the caption.

# =================================
# C-Shell family: sample login file
# =================================

# 1. Environment variables
setenv PAGER less
setenv VISUAL vi

# 2. Command line editor - Tcsh
bindkey -e

# 3. File creation mask
umask 077

# 4. Terminal settings (for remote host only)
stty erase ^H
# stty erase ^?

# 5. Display welcome message
echo "Welcome Harley."
echo "Today is `date`."
echo

# 6. System information
echo "Last three logins:"; last `whoami` | head -3
echo
echo "Current users: `users`"
echo
echo "System uptime:"; uptime
echo

Section 1 of the login file defines the environment variables. We set the default paging program to less and the default text editor to vi. (Chapter 12: variables; Chapter 21: paging programs.)

Section 2 sets Emacs for our command line editor. Strictly speaking, you don't need to set this option, as Emacs is the default. However, I like to set it explicitly as a reminder. Since the C-Shell does not support command line editing, we only need this section for the Tcsh. (Chapter 12: command line editing, bindkey.)

Section 3 sets the file creation mask to control the default permissions for newly created files (Chapter 25: file permissions, umask.)

Section 4 is used only for login files on a remote host. You do not need this section when you are using Unix or Linux on your own computer. The stty command sets the key mapping for the erase signal. I have given you two possible commands. Use whichever one works best with your keyboard. (Chapter 7: erase signal, stty.)

Section 5 displays a welcome message. You can change this to whatever you want. (Chapter 8: date; Chapter 12: echo, command substitution.)

Section 6 displays interesting information about the system. (Chapter 4: last; Chapter 8: whoami, users, uptime; Chapter 12: echo, command substitution; Chapter 15: pipeline; Chapter 16: head.)

Jump to top of page



Exercises

Review Question #1:

What is an initialization file?

Name the two types of initialization files.

What is a logout file?

Review Question #2:

What is a dotfile?

What is an rc file?

Review Question #3:

What is a login shell? What is a non-login shell?

Why is the distinction important?

Review Question #4:

You have a list of favorite aliases you like to use, so you decide to put the definitions in one of your initialization files. Which file will they go in, the login file or the environment file? Why?

What else goes in this file?

Applying Your Knowledge #1:

Look carefully in your home directory to see if you already have a login file and an environment file. (You can use the command ls -a to list your dotfiles.) If so, take a look at what is inside each file. (Either use the less command or open the files in your text editor.)

Applying Your Knowledge #2:

Create (or modify) a login file for yourself using the sample file in either Figure 14-3 or 14-6 as a template. If you have an existing file, save a copy under a different name as soon as you open it within your text editor, before you make any modifications. That way, if you make a mistake, you will be able to change back to the original version.

Applying Your Knowledge #3:

Create (or modify) an environment file for yourself using the sample file in either Figure 14-4 or 14-5 as a template. If you have an existing file, make a backup copy as described in the previous exercise.

Applying Your Knowledge #4:

Create a logout file for yourself. If you are not sure what to put in it, use the echo command to say goodbye to yourself. The name you use for this file depends on which shell you are using (see Figure 14-1). If you are using the Korn shell, you will have to trap the exit signal (explained in the chapter and in Figure 14-3).

For Further Thought #1:

The POSIX standard mandates that a shell should support a login file and an environment file, but not necessarily a logout file. This implies that the logout file is less important than the other two files. Why should this be the case?

For Further Thought #2:

On many systems, when a new account is created the new userid will automatically be given a default login file and, sometimes, a default environment file. Why is this a good idea?

Would you advise a new user to modify these files or leave them alone?

Jump to top of page