WEEK 1

Introducing the C Shell


Introduction to Day 1

This chapter will introduce you to the C Shell. In the following pages, you will learn what the C Shell is and why you would choose it over the other command shells available with your UNIX system. The different C Shell options, how to use the shell interactively at your terminal, and how to use the C Shell noninteractively for shell scripts are covered in this chapter. You will find out how to determine the setting of your login shell and how to change your current login shell to be the C Shell. The remainder of this chapter is devoted to a feature that first set the C Shell apart from other UNIX shells--command history. At the time the C Shell was introduced, no other shell provided this type of facility. You will learn about history events, how to recall them, modify them, and reuse them. This feature is one that you will likely find useful as you progress through this book. If you choose to continue using the C Shell, the history event feature will be a valuable tool as you use UNIX for work or pleasure.

Setting Today's Goals

Today you will learn how to

What Is the C Shell?

When you enter commands at the command prompt on your terminal screen using the UNIX operating system, you are interacting with a special-purpose program. In UNIX, the programs that process the system's commands are called shells. This book teaches you how to use a specific shell program called the C Shell. When UNIX was first written and put to use at AT&T Bell Labs in the early --70s, it too had a command shell. This early UNIX went on to become the System V that is the dominant standard in the industry today. The same command shell--named the Bourne Shell, after its author Stephen Bourne--is still used and distributed today with every version of UNIX.

In 1978, a copy of UNIX was given to the Computer Science Department at the University of California at Berkeley. Under a contract from an agency of the United States government, the students and faculty developed the first 32-bit virtual memory version of UNIX. As part of that effort a new command shell, dubbed the C Shell, was written. This new shell provided a number of features that were not available with the Bourne Shell.

The new functionality added to the C Shell was designed to benefit the interactive user. Two important additions were the history mechanism, allowing the user to reuse and modify previously executed commands; and job control, which provided for more control over tasks initiated by the user. A third very visible change made with the C Shell was the new programming language for writing shell programs, or scripts.

The architects of Berkeley UNIX and the C Shell patterned the shell programming language for their new shell after the C programming language. Their aim was to make writing shell programs easy for users, many of whom already were proficient in the C programming language. If you are familiar with the now popular C programming language, you will find writing shell scripts for the C Shell easy, because doing so is much like writing a C program.

Why Use the C Shell?

The original UNIX system and the first Bourne Shell were designed and written by programmers mainly for users who were programmers. In today's terms, the original versions of UNIX were no frills. The users of these early systems were more concerned with developing the operating system, with its commands and tools, to accomplish the tasks that were a part of their everyday jobs than in making it user friendly. User facilities were developed and enhanced only after the UNIX system left the confines of the Bell Labs and entered the world of academia and, later, the public marketplace. Depending on the type of user that you are and the nature of the job for which you are using UNIX, you will have a varying amount of contact with the shell. You may be a user who sees only a menu of selections and the programs behind the selections. If this is the case, then it matters very little which shell you choose, because your interaction with it will be minimal if not nonexistent. If, on the other hand, you are logging on and dealing directly with the shell on a day-to-day basis, then your choice of shells becomes very important.

As you complete each chapter of this book, you will become more comfortable and proficient with the commands and features of the C Shell. The hallmark features of the C Shell--command history and job control, as well as the C-like programming language--will be important labor savers, and perhaps even sanity savers. When you find that you don't have to retype entire command lines if you've used them just moments before, you will appreciate the history mechanism.

You will learn about C Shell job control at the end of this book. Using job control, you will start a procedure, answer its questions, interrupt it, and put it in the background, freeing up your terminal to do other work while the procedure processes behind the scenes. If the job needs input, it will inform you. You can then bring it back, supply the data or answers, and then return it to the background. On a simple terminal without windowing, this helps you be more productive. Even with windowing, you can do more work with your existing open windows.

Now, back to the question, Why use the C Shell? Well, if anything I have said in the last few paragraphs appeals to you, then you should use the C Shell. None of the features just discussed are a part of the Bourne Shell. There are other shells, available on some UNIX versions, that incorporate some or all of these features in one form or another. The difference between those other shells and the C Shell is that, if you move from one version of UNIX to another, you can't depend on finding those other shells. The two command shells you will find in all versions of UNIX are the Bourne Shell and the C Shell.

Changing Your Login Shell

I hope that you are reading this book because you have an interest in the C Shell. If you are going to work with the C Shell, you can make it your default shell or start it each time you want to change temporarily from your default to the C Shell. The next section shows you how to determine whether you have the C Shell as your default, and how to change to or from it, if you choose.
Determining Your Login Shell
When you log in to your system, UNIX starts a shell, which is the program that displays your initial command prompt for the session. That shell is referred to as your login shell. Your system administrator set up your account on the system and chose your login shell. The name and location of that shell--its pathname--is maintained by UNIX in the system password file. Exiting the shell logs you out of the system. The password file contains information describing your account on the system: your login name or account, password, user ID number, group number, and home directory. Another field contains descriptive information, which could be your full name, a work phone number, your office location, or other pertinent information, in a free format. The last item in your account record is your default, or login, shell, which is kept as a full pathname like /usr/bin/csh.

There are two easy ways for you to find out which shell has been set up as your default shell. One way is to look in the password file in your account record to see what is in the last field in the record. This always contains the path of the default shell. The password file is /etc/passwd. If you use the UNIX grep command--a text searching program--you won't have to look through the entire password file to locate and display your record. To use grep, you enter the following command (here shown in bold) on your system:

1 % grep David /etc/passwd
davide:AQ1#BpsGN&mY:100:20:David Ennis, x5021:/usr/davide:/usr/bin/csh
2 % _

Note: The grep command searches for patterns in text. The pattern can be simply literal text, such as in the preceding example where I searched for my account name, davide. The text usually is found in one or more files that you specify to grep on the command line. The file was /etc/passwd in my example. With no options selected, the default behavior of grep is to display any lines of text that contain the match pattern. The line of text that follows the grep command, beginning with davide, is the text that was located in the password file.

The password file contains records, which are lines of text, one for each login account on the system. Each account record contains seven fields delimited with colons (:). The seven fields contain the following information :

  1. Account name ( davide).

  2. Encrypted password ( AQ1#BpsGN&mY).

  3. User ID number (100).

  4. Primary group number (20).

  5. Descriptive information ( David Ennis, x5021).

  6. Home directory path (/usr/davide).

  7. Default shell path (/usr/bin/csh).

If you examine the line displayed by the grep command, you will see your default shell at the end of the line, just after the last colon (:) character. My default shell is, of course, /usr/bin/csh, otherwise known as the C Shell. In the next sections, you will learn how to change your default shell. If you choose to make a change in your default shell selection, this field in the password file is where the change is made. The next time you log in to the system, your choice takes effect.

There is a second method used to determine your default shell setting. When you log in to the system and your login shell is started, it sets a special shell variable to the value of your current shell. Variables are the topic of Day 4, --Shell Variables, Part I" and Day 5, "Shell Variables, Part II." The specific variable that you are interested in, called$shell always contains the value of your current shell.

The system looks at the last field in your password record to find your default shell. When you examine $shell from a login shell, the value of your current shell is the same as your default shell setting. The easiest way to look at a shell variable is to use the shell's built-in command echo to display its contents. The echo command and the rest of the C Shell's built-in commands are the topic of Days 8, 9, and 10 of this book. Enter echo $shell on your system to find out the setting of your default shell:

2 % echo $SHELL
/usr/bin/csh
3 % _

The shell echo command displays the contents of the shell variable$shell. In the preceding example, you see that mine is set to /usr/bin/csh, which is the same as what is in my password file record displayed earlier. After you have chosen and changed your default shell setting, it will not change unless you or your administrator alters it.

A qualification to this statement has to be made if you are working in a networked environment where you have access to more than one system. It is possible for you to have a different default shell setting on another host that you have access to over the network. This is especially true if the machine is from a different vendor, or if it is administered by a different person, group, or organization. You will want to check those hosts in the same manner and perhaps change your default shell on those hosts, so that you are using the same shell on all systems that you access. This will make using UNIX much easier for you.

Setting Your Regular Default Shell
Now that you know what your default shell setting is, how can you change it if you want to do so? There is a UNIX command which does just that for you. The chsh command, which stands for change shell, enables you to change the setting for your default shell. When you use chsh to make a change to your default, the change does not take effect until you log out and then log in once again. At that time, you will have the shell that you selected as your login shell. Although chsh is not a part of the C Shell, its syntax is shown here so you will know how to change your default shell setting before you go further in the book.

The syntax for the chsh command is chsh default-shell-path

where the default-shell-path is the full file pathname of the command shell program that you want to use as your default shell. Check with your system administrator if you cannot locate the shell of your choice.

Example: chsh /usr/bin/csh

When you use the chsh command to change your default shell, it changes the contents of the last field of your password file record to reflect the new shell pathname you entered on the command line. This change stays in effect until the next time you use chsh to change your default to another value. This change is what I like to call temporarily permanent, because it can be modified but is otherwise permanent. Next I will show you how to quickly change your current shell without using chsh. This change is temporary in the true sense of the word.


Caution: When you use chsh to change your default shell setting, be sure that you properly spell the pathname for your new shell. If you misspell any part of the pathname and don't catch your error before logging out of the system, your logon will fail when you attempt to log in the next time. Most likely, the system will be unable to locate the file that you give to chsh and will not be able to start a login shell for you. The only way to fix this is to contact your administrator and ask to have the pathname corrected in your password entry. So be careful!
Temporarily Changing Your Shell
Occasionally, you will need to change your shell to one that is different from your default shell. If the change is short-term, you do not want to use chsh, having to log out and log in again simply to change your shell for a short period of time. There is a simpler solution that I'll present to you now. Whenever you run any command in UNIX from the command prompt, your current shell process is paused, while your entered command is run. When your command finishes, your current shell process is started again, and it displays a new prompt for your next command. You can take advantage of this behavior of UNIX to temporarily change your shell to a different command program.

To make this temporary change, at your command prompt you simply enter the command name of the new shell you wish to run. If, for example, you find that your default shell is the Bourne Shell, and you want to run the C Shell at this time, enter csh at the command prompt. The next prompt you see will be coming from the C Shell and not from your default Bourne Shell.

$ csh
% _

Note: In the preceding example, it may not be readily apparent to you that I have switched shells. I have given you a subtle hint in the command prompts that are shown. The first prompt, a dollar sign ($), is the typical Bourne Shell prompt. The second prompt, a percent sign (%), is typical of the C Shell. Later in today's lesson, you'll learn about history events and event numbering. On Day 6, "Customizing the User Environment," you'll learn how to include this event number in your command prompt to help you recall history events. When your command prompt includes this event number, you'll have a better visual clue that you have changed to a new shell. Your event number will then change from its current value back to one (1) with the start of a new shell process.
When you have finished using the C Shell and want to return to your original shell process, you only need to end the C Shell. Ending the C Shell is covered in detail later in today's material.

Starting the Shell

Now it's time to look at the different ways that you can start the C Shell, the options that are available to you, and how you can take advantage of them. The next few sections introduce you to the two modes in which the shell operates--interactive and noninteractive. The interactive mode is used when you are using the shell at your terminal. The noninteractive mode of the C Shell is used when you run a shell script, where the shell takes its commands from the script file. The syntax for the C Shell is shown in the following syntax box, with all of the options available for starting the program. These options are reviewed later in today's lesson. The syntax for the csh command is csh [-bcefinstvVxX] [argument...]The csh command has twelve option flags, shown in the square brackets, that affect the operation of the shell. Some of these options are more appropriate to either the interactive or noninteractive mode of operation of the shell, but none are limited to one or the other. Each of the options is explained briefly here and in more detail where appropriate later in the book.

OPTIONS

-b
Marks the end of options that are applied to the C Shell. Options after this one are passed to the script or command started by the shell. This permits passing options to a script without confusion.

-c
Reads commands from the first filename argument(which is required). Any arguments following the filename are placed in$argv, the argument-list shell variable.

-e
Exits from the shell if a command ends abnormally or returns a nonzero exit status.

-f
Starts the C Shell fast by inhibiting the reading of the .cshrc file and, if the shell is a login shell, the .login file upon startup. This accelerates the startup of the shell.

-i
Forces interactive mode. The shell prompts for command-line input, even if standard input is not apparently a terminal device.

-n
Interprets but does not execute commands. Used to check the syntax of C Shell scripts for errors.

-s
Uses standard input to read commands.

-t
Takes a single command line as input. The backslash character (\) may be used at the end of each line to allow continuation of the command on following lines.
-v
Sets the $verbose shell variable, enabling echoing of command input after history substitutions (and before other substitutions) have been made, but before the command is executed.

-V
The same as -v except that $verbose is set before the shell reads . cshrc.

-x
Sets the $echo shell variable, enabling echoing of command input after all substitutions have been made.

-X
The same as -x except that $echo is set before the shell reads.cshrc.

Except for -c, -i, -s, and -t, the first argument that is not an option is assumed to be the name of a command or script. This argument is passed as argument zero, the name of the command program. Subsequent arguments are added to the argument list for the command or script.

Interactive use of the C Shell
You will likely use the C Shell most often in its interactive mode, while you are sitting at the keyboard entering commands to get your computer to do your bidding. Each time a C Shell is started, it looks in your home directory for its configuration files. These files, .cshrc and .login, contain commands that are executed by the shell. When the system starts your first shell, the login shell, it does so by prefixing a dash

(-) to the name of the shell to change the name. This acts as a special flag to the login shell so that it can read the .login file if it exists in your home directory.

If you look at the syntax for the csh command, you'll notice that it has many options. You may think that, because the system starts your login shell, you don't have the ability to set any of these options. This is not the case, however. There is a method available by which you can set these options for your login shell if you choose to. Using the special variables, you can set these options either temporarily, for a single session, or permanently, where they will be set every time you log in to the system.

To set an option on temporarily, you can simply set its corresponding shell variable at a command prompt in your login shell, or any other shell. The option remains in effect until it is unset or the current shell session is ended. It is not reinstated for later shell sessions unless you specifically set it again at the command prompt.

For any option that you want to be in effect for all of your interactive shell sessions, the method is basically the same. You set the options by setting the shell variables. The difference is that each time the shell starts, it--rather than you'sets the variables at the command prompt. To do this, you put the commands to set the variables in one of your startup files, .cshrc or .login. You'll learn more about these two files and how they affect the operation of the shell on Day 6.

Noninteractive Use of the C Shell
Whenever you write and use a C Shell script or use a C Shell script written by someone else, you are using the shell noninteractively. The main difference between the two modes--interactive and noninteractive--is that the noninteractive shell does not issue prompts for input from the terminal. You can execute a single command, supplied as an argument on the command line, or a shell script containing multiple commands, in this mode. Using the shell noninteractively, you have several choices for setting any necessary options, whether you are running a single command or a shell script. You can choose to

  1. Add the option to the command line when you invoke a single command or script using csh directly.
  2. Use the set command within a shell script to set the shell variable corresponding to the desired option.
  3. Set the option on the first line of a shell script where you want to be able to invoke a script by name without using the csh command (this is covered in more detail on Day 12, "Applied C Shell Programming, Part I--).
Command-Line Options
The options of the C Shell give you control over how the shell operates. As you learned earlier, you can set options individually, through the use of command-line options or option-related shell variables. In this section, I'll give you a brief overview of each option of the C Shell. In the remainder of the book, the options are revisited and explained in more detail when they relate to the current topic.
Break Option, -b
When you choose to invoke a command or script from the command line using the csh command directly, there are situations when you want to pass options or arguments both to the C Shell and to the command being executed by the shell. To do this properly, you often must separate the options to csh from those intended for the command being executed by the shell. The -b option is used to signal the end of the options intended for the C Shell and the beginning of those directed at the command being invoked. In the following example, the options -f and -v are passed to and processed by the csh command, whereas the options -q and -x are passed to the script myscript for whatever processing it may do:
3 % csh myscript -f -v -b -q -x
4 % _
This separation happens by a special arrangement in which the csh command takes the options up to, but not including, the -b option for itself and passes the options after the -b option to the command that it is executing.
Script File Option, -c
If you want to start the shell in a noninteractive mode and direct it to take its command input from a file, you would use the -c option. This informs the shell that the first filename argument (that is, not an option flag) should be read for commands to be executed. Any arguments that appear on the csh command line after this first argument are placed in the special shell variable $argv, which is the argument list variable. In the following example, the -c tells the shell that scriptfile contains the commands that it should read and execute:
4 % csh -c scriptfile -v -a infile1 infile2
5 % _
The options and file arguments that follow scriptfile on the command line are put into the $argv argument-list variable for use by the commands within scriptfile. The difference between this example and the one for the -b option is that here only the -c is processed as an argument to the csh command. In the case of scriptfile, it may not otherwise be clear to the C Shell that this file contains commands, so you use the -c option to indicate that fact to the shell. Later, you'll learn methods by which you can specify unambiguously that a file is a shell script, and thus not need this option.
Exit-Upon-Error Option, -e
The -e option modifies a default behavior of the C Shell when executing shell scripts. Normally, if a command being executed from within a shell script returns a nonzero exit status, or abnormally terminates, the script continues to execute, unless directed otherwise by the logic of the script. If the -e option is included when you start the csh command or the script file itself, execution of the script ceases immediately when a command within the script terminates abnormally or returns a nonzero status. For some simpler scripts, this eliminates the need to test the outcome of each command executed as part of the script. If you want your script to exit immediately when an error occurs, use this option. If it is necessary to take additional steps when a command fails within a script, these steps should be explicitly written in the script, and the -e option should not be used.
Fast Start Option, -f
When the csh command startup processing occurs, one step the C Shell takes within that startup is to read and process commands found in the .cshrc file from the user's home directory. Normally, the contents of the .cshrc file are used to tailor the interactive environment of the user. These commands often are not appropriate for the noninteractive environment, and on occasion they may even cause errors to occur. The -f option tells the csh command to skip the reading of this file, typically resulting in a faster startup of the shell process. The -f option is used most often on the special first line of C Shell scripts.
Forced Interactive Option, -i
The -i option causes the shell to prompt for input even if it appears that its input (standard input) is not a terminal (character-special device). If you are trying to use the C Shell from a terminal-like device but you can't get a prompt, you can try this option to get the shell to issue you a prompt.
Nonexecution Option, -n
If you are writing a shell script and want to check it for syntax errors, you can use the

-n option. With this option, the shell will parse and interpret all of the commands in your script but will not execute them. If there are errors in the script, the parsing and interpreting will report them, as it would during a regular execution. Unlike the regular execution of a shell, script processing proceeds to the end of the script regardless of whether errors are encountered and reported.

Standard Input Option, -s
With the -s option, the shell takes its input from standard input. If this option is used with the csh command invoked from within a script file, the shell process that is started takes its commands from the lines immediately following the csh command line until an end-of-file is encountered. If this option is used starting csh at the command prompt, the shell takes its input from the terminal, but not prompt for input as it normally does. This option is rarely used.
Single Command-Line Option, -t
The usual behavior of the shell is to read multiple command lines from its input source. The -t option causes the C Shell to read a single input line from standard input. The backslash (\) can be used at the end of each line to escape each newline character for continuation of the command line on subsequent lines.
Verbose Option, -v
The -v option causes the C Shell to set the verbose shell variable. When the verbose shell variable is set, the shell echoes each command just after all history substitutions have been made and before any other substitution processing is done on each command line. This option is used when there is a need to debug shell scripts and view what the C Shell is doing as it processes each command line within the script. The -v option is not usually left on a script that is used regularly, for it produces a considerable amount of output on most scripts.
Verbose .cshrc Option, -V
If you have not set the -f option, the C Shell first reads the startup file .cshrc before reading the first line of your script. At times, while debugging a script, you want to view what the C Shell is doing during this processing prior to reading your script. Like the

-v option, the -V option causes the shell to set the verbose shell variable and to echo commands just after history substitutions have been made. The important difference between the two verbose options is that this one, -V, sets the verbose shell variable before the shell starts to read the .cshrc startup file. This allows you to view the processing that the shell performs on your startup file and that could be affecting how your script executes.

Echo Option, -x
The -x option causes the C Shell to set the echo shell variable. When the echo shell variable is set, the shell echoes each command after all substitutions--history and metacharacter--have been made and just before the command is executed. The -x option, like the -v option, is also used when there is a need to debug shell scripts and view what the C Shell is doing as it processes each command line within the script. The -x option also is not usually left on a script that is used regularly, for it produces considerable amounts of output on most scripts.
Echo .cshrc Option, -X
In a manner like that of the -V option, the -X option causes the C Shell to set the echo shell variable prior to the start of reading the .cshrc startup file. As with the -x option, the -X option echoes each command line after all substitutions have been completed.

The -X option is also not left on scripts that have been debugged; it too produces volumes of output.

Ending the Shell

When you are ready to end the C Shell, you can simply enter exit at the command prompt. This terminates your current shell. If that happens to be your login shell, you are logged off of the system, and a login prompt appears, as in this example:
% exit

Welcome to UNIX

Login: _

Another way to end the C Shell is to enter^D, that is, to hold down the Control key while you type the letter D.^D, also represented as Control-D, is the UNIX end-of-file (EOF) character, and when the C Shell sees the EOF on input, it takes that to be the end of the command file and terminates. This can be a dangerous way to end the shell.

Some UNIX commands can accept input from the terminal rather than from a file specified on the command line. To indicate to these commands that you are finished with input, you use the same ^D EOF character. If you were to accidentally enter an extra^D, your shell would end when you least expect it to end. To avoid this, the C Shell has a special shell variable that acts as a switch to disable ^D for exiting the shell. That special variable is $ignoreeof, which, as it name implies, tells the shell to ignore the EOF character.

To find out whether you have this switch set, you can use the set command to display all of your shell variables and their current settings. See the example in the next section to see what the output looks like. In that example, you'll see that there is a line with the word ignoreeof on it. This indicates that the $ignoreeof shell variable is in fact set to ON. If it were not set to ON, you would not see ignoreeof in the list displayed by the set command.

On Day 6, you'll learn more about a special file, .logout, that you can use to configure special processing that occurs when you exit from your login shell and log out of your system.

Command History

You will recall that, at the start of this day, I mentioned command history as a useful and distinguishing feature of the C Shell. In this section, I'll show you how you can set up the C Shell to keep a history. Also, I'll show you how to recall commands, modify them, and reuse them to make working interactively with the C Shell more productive and easier.
Setting the History Variable
The first step in using command history is to set the C Shell$history variable. This shell variable sets the number of commands that the shell keeps in its history, before discarding the oldest saved command. You can set the variable to any number, but typically you set it initially to a reasonable value like 50. Later, as you become more experienced using the C Shell, you will likely increase this number so that you can keep a bigger backlog of command history. First you can check to see if, in fact, you have the $history variable set. Your system administrator may have given you a startup file, as part of the initial configuration of your account, that included a command line to set this variable for you. To find out whether you already have $history set, you can use the C Shell set command to show all of the currently defined variables. Here is an example:
5 % set
argv         ()
cwd          /usr/dave
history      20
home         /usr/dave
ignoreeof
noclobber
path         (/bin /usr/bin /usr/dave/bin /usr/lib .)
prompt       ! %
shell        /bin/csh
status       0
term         vt100
6 % _

Note: What you will see when you enter the set command at your command prompt will probably be different from what is shown in the example, but in general this is similar to what you will see. The first column is the name of the variables that you have set in your current shell session. The second column is the value that the variable contains. Notice that two of the variables, ignoreeof and noclobber, do not have values. These are special variables that behave like switches. When they appear in the list they are ON, and when they are absent from the list they are OFF. These and the other reserved shell variables are explained in detail during Days 4 and 5.
In the output displayed in the preceding set command example, notice that there is a line that begins with history and has the number 20 after it. If you see a similar line in the output from your set command, then you know that you have the command-history feature enabled for your shell sessions. Don't worry now about the value set for your $history variable. If it is set, the value is likely to be something reasonable and will be adequate for working the examples that follow. If you choose, you can edit your .cshrc file and change the value setting for the $history variable.
Viewing History
The C Shell has a command that you can use to look at your history list at any time from the command prompt. That command is history, and when entered, it displays all of the commands in your history list, up to the number set in the $history variable. Consider this example:
6 % history
1  grep David /etc/passwd
2  echo $shell
3  csh myscript -f -v -b -q -x
4  csh -c scriptfile -v -a infile1 infile2
5  set
6  history
7 % _
When you enter the history command at your shell prompt, your output will be different from what I have shown here but should look similar in format. What you see is a list of the command history, those commands that you have entered at the shell prompt since you logged onto the system. Your output may not have all of the commands that you have entered if the number exceeded the value of your $history variable. In that case, you will see only the most recent commands listed. For example, if your $history is set to 20, but you have entered 30 commands since you started on the system, your history list would start with command number 11 and end with command number 30.

The commands contained in your history list are referred to as events. You should have noticed in the last example that each of these events has a number shown next to it in the output from the history command. These numbers are called event numbers and are important because this is how you identify the command in history that you want to reuse and possibly modify. Throughout the remainder of this book, I will use the terms event and event number to refer to command lines in the history list and the number associated with them.

Recycling Events
The simplest thing you can do with history events is to repeat them unchanged. Say, for example, you want to use the UNIX command ls to look for all the files that end with.txt. You might want to find files like this in several subdirectories. To do so, you would enter at your command prompt the command in the following example:
7 % ls *.txt
memo.txt
test.txt
welcome.txt
8 % cd stuff
9 % !7
ls *.txt
letter.txt
tutorial.txt
10 % _
In this example, you see that there were three files in the current directory that end in.txt. In event 8, I used the cd command--which you will learn more about on Day 8, "C Shell Built-In Commands----to change the current directory to one called stuff. Event 9 then does something interesting. It recalls event 7, the ls command, which then displays the two files in directory stuff that end in.txt. The syntax for the history recall commands is shown here. All of the commands begin with the exclamation character (!), sometimes called a bang. This character informs the C shell that what follows refers to a history event.

To recall an event by its event number, use this syntax: % !event_number

To recall the last event, use the following syntax: % !!

To recall an event by a relative event number, use % !-relative_event_offsetwhere the relative_event_offset is subtracted from the current event number to get the number of the event to be recalled.

To recall an event by text content, use this: % !text_string_beginning_of_eventor this:

% !?text_string_contained_in_event[?]

The following sections explain in greater detail how to use these variations on recalling history events.

Recalling by Event Number
One of the easiest ways to recall events is by event number. You saw an example of this in event 9 where I typed !7 to recall event number 7. When you recall history events, the C Shell always first displays the event being recalled. If you look again at event 9, you see that the ls command from event 7 is displayed before it is executed, producing the output shown in the example. This permits you to verify the command that was executed as a result of the recall. Depending on the setting of your $history variable, you might on occasion try to recall an event that the shell has discarded. When the number of events exceeds the value in $history, the shell discards the oldest command before adding the newest one to the list. If you reference an event that is no longer in the history list, the shell returns the command prompt with no action taken.
Recalling the Last Command
In the preceding syntax box, you saw that there is a special case for recalling the last command executed. Because frequently you will want to repeat the same command immediately, this special method is provided to make doing this recall easier. To recall the last event. use !! at the command prompt.
Recalling by Relative Event Number
Frequently, you will want to repeat an event that you performed a few commands earlier. It might even still be displayed on your terminal screen, or you remember that it was three commands ago. The C Shell allows you to recall events relative to the current event number by typing the bang (!) followed immediately (no spaces, please) by a minus

(-) and the number of events back that you want to recall. If you want to recall the command three events ago, you would enter !-3:

10 % !-3
ls *.txt
memo.txt
test.txt
welcome.txt
11 % _

Do the simple arithmetic to find that the current event (10) minus 3 is equal to 7, which is the original ls command that looked for files ending in.txt. The event recalled is echoed as always and then executed, producing the output listing all of the files that match.

Recalling by Event Text
Once you get more comfortable with recalling events and you increase the setting of your $history variable to, say, 100, it will become more challenging for you to remember the event number of some command that you did an hour ago and now want to repeat. For just this situation, the C Shell has yet another way to recall events.

Instead of following the bang with an event number, you can follow the bang with the name of the command that you want to recall. The shell searches backwards from the most recent event until it finds a match. That event is then displayed and executed. The one restriction is that the text must match exactly to the beginning of the command line originally entered. For example, to recall by text the echo command from event 2 (see earlier in this chapter), you would use!echo:

11 %!echo 
echo $shell
/bin/csh
12 % _

The shell searches backwards through the history list until it finds an event that starts with echo. If it does find a match, it displays the event and then executes the command. In event 11, I recalled the most recent event that began with the string echo. The shell displayed the command, echo $shell, and then performed the command, producing the output /usr/bin/csh.

Because this method only matches to the initial characters of an event, it is not always easy for you to use to recall the specific event you have in mind. So the C Shell provides an alternate way to match an event using text rather than an event number. In this method, as in the last, you use the bang and the text you want to match, but between the bang and the text, you put a question mark(?). This tells the shell that you want to match the most recent event that contains the text anywhere in the event string. Perhaps you have done more ls commands since the one you are interested in recalling, but they had different match strings than the one you want. You can recall an older event by matching to a string within the event, instead of strictly at the beginning. You would do so by using a command like that shown in the following example:

12 % !?myscript
csh myscript -f -v -b -q -x
13 % _

In this example, I recalled event 3 from earlier in the chapter by matching to the string myscript. If I had tried to match to the beginning of the line with !csh, I would have recalled event 4 instead, because it was the more recent event that matched to csh at the start of the command. With this method, I was recall the event I wanted by matching to text contained within the event.

Optionally, you can follow the match text by another question mark(?). This is required only when you want to follow the match text with new text to be appended to the recalled event. The additional question mark is then needed to tell the C Shell where the match text ends and the appended text starts:

13 % !?myscript? appended_filename
csh myscript -f -v -b -q -x appended_filename
14 % _

Here I recalled the same event as before, but I also added a filename, appended_filename, to the end of the command as part of the action of recalling the event.

Modifying Previous Events
Thus far, you have learned how to recall events to repeat them without change. Now you'll see how you can make changes to an event as part of the recall commands you have learned.
Words Within Events
Before you can modify previous events, you must know how to specify which word or words in the event you want to change. This section shows you how to make changes to one or more words in an event when you recall it from the history list.

Table 1.1 lists the C Shell word designators and a brief description of what each one indicates when used in recalling an event for modification.


Table 1.1. Event word designators.
Designator		Description
#		The entire command line entered up to this point.
0		The first input word (the command).
n		The nth argument on the command line.
^		The first argument on the command line (that is, 1).
$		The last argument on the command line.
x--y		The range of words from word x to word y.
-y		The range from 0-y.
*		All of the arguments, or a null value if just one word is in the event (that is, just a 			command).
x*		Abbreviates x-$.
x-		Like x* but omits word $.

Modifying Previous Events
When you enter new commands or recall previous ones from the history list, you can include selected words from previous commands. The most common history substitution that you will use is to include the last argument from the previous command in a new command. Typically, the last argument of a command is a filename that you want to reuse on the next command. To see how this can be done, look at the following example:
14 % ls testfile.txt
testfile.txt
15 % cat !$
This is the text that was in a file "testfile.txt--
in my home directory /usr/dave. I will use this file
in examples where I want to look at text in a file.
16 % _

In this example, I first did an ls command to see that the file testfile.txt exists. The ls command displayed the filename, showing that the file is present. Then I included the same filename, testfile.txt , in the next command, which I entered by using the history word designator !$ in place of a filename with the command cat. The shell made the substitution of the last word from the previous command onto this command line, and the result was to display the contents of the file on my terminal. You could also just as easily use the word modifier !^ to indicate that the first argument in the previous command should be substituted. In the last example, because there is only one argument, the first and last argument are the same, so the result would be identical. In all cases, history word modifiers must be prefixed with the bang character to indicate that a history reference follows.

In the last example, using just the bang(!), I referenced the most recent event. If you need to reference an earlier event, you have to further qualify the modifier in the command. If you want to use the ls command on the files that were referenced in event 13, you could use the following command:

16 % ls !13:$ !13:^ 
ls appended_filename myscript
appended_filename
myscript
17 % _
In this example, I substituted the last argument word and the first argument word on the ls command. The shell echoed back the resulting command after the substitution and then it executed the command. The filenames that appear, appended_filename and myscript, are the results displayed by the ls command.

Once again, there is a another way I could have done the last example and still have received the same results. Rather than using the event number in the substitution, I could have used one of the forms of text recall, as I did in the simpler examples earlier in this section. Then, in place of the event number!13, I could have used either !csh to match on the command name or either !?myscript or !?appended_filename to match to text within event 13.

Lastly, you can use one of the word range designators to include some portion of the arguments from a previous event in your current command. I will leave that to you as an exercise to experiment with independently as you explore the possibilities of history substitutions and event modification.

Summary

In Day 1, you were introduced to the C Shell and presented with many reasons why it should be your default shell, the one that you use in your day-to-day work on the UNIX system. I showed you how to find out what your default shell is set to and how to make the C Shell your default shell.

You learned about the two modes of operation of the shell: the interactive mode, in which you receive command prompts from the shell at your terminal; and the noninteractive mode, in which the shell is processing a script file that contains C Shell and UNIX commands. Ways to end the C Shell were also demonstrated, and the options for starting up the C Shell were presented with brief explanations.

The last part of Day 1 introduced the C Shell's command history facility. You were shown a number of methods for recalling events from history and how to modify those recalled events. I also presented the event word designators that enable you to use selected words from previous events in a new command.

In Day 2, "Metacharacters," you will learn about shell metacharacters, which are used in filename generation, pattern matching, input and output modification, and much more. This material will be the foundation upon which your effective use of the C Shell will be based.

Related UNIX Topics
This chapter presented some new concepts and commands. Here is a list of some of these concepts and topics, with suggestions for sources of further information. Dot Files:

Consult Appendix E at the end of this book for examples of the --dot" files".cshrc, .login, and.logout. You can modify these files to customize your shell environment. Doing so is covered in Day 6.

Other Shells: Look in Section 1 of your UNIX manuals for the man pages for the more and pg commands. Determine which of these commands is available on your system, and learn more about the different capabilities of these versatile commands.

Q and A
Q What are some of the features that distinguish the C Shell from the Bourne Shell?

A The C Shell has a history facility, by which you can recall command lines that were previously executed. You can then repeat those command lines or modify them and execute the modified version. Additionally, the C Shell provides a job control capability that gives you the ability to exert more control over your background processes. This feature is covered in the last chapter of the book.

Q What is the command that I would use to change my default shell? Where is the C Shell usually found on UNIX systems?

A The command used to change your default shell is chsh. To use this command, you give it a single argument, which is the pathname of the shell that you want to have as your new default. On some systems, the C shell is in /bin/csh, whereas on others you will find it in /usr/bin/csh. Typically, if your system is Berkeley-kernel based, the first path applies. On the other hand, if yours is a System V-based kernel system, look for the C Shell in /usr/bin/csh.

Q How can I quickly repeat the last command that I entered?

A The quick way to do that is with the history recall of!!. All history substitutions begin with the exclamation, or bang, character(!), and the second exclamation mark is a short hand for the previous command.

Q How can I make a quick change of one word of the last command and rerun it?

A The Quick Substitution character is the carat(^). Enclose first the string you want to change in carats, followed by the string to replace it with, and a closing carat (for example,^change_this^to_that^). The first occurrence of the search string will then be replaced by the second, and the resulting command line will then be executed.

Workshop

The Workshop provides several sections to aid you in reviewing the topics covered in today's lesson. There is a quiz section to help you reinforce your understanding of the material presented in Day 1 and exercises to give you practice applying what you have learned. Take the time to review these questions and exercises, so that you understand the concepts before you begin the next day's lesson. The answers are provided in Appendix F, --Answers to Quizzes and Exercises."
Quiz
  1. How can you find out what the settings are for your shell variables?
  2. What is the difference between the two modes of C Shell operation?
  3. How would you recall an event in each of the following ways?
  4. How would you include the first argument from your last command line on your next command line?
  5. How would you include the last argument from your previous command on your next command line?
Exercises
  1. Experiment with event modification.
  2. Work with substituting words from previous events into new commands.
  3. Find out more about the capabilities of using word ranges to include more than one or less than all of the words from a previous event.