4. The Shell and Command Processing
The UNIX program that interprets your commands is called the ``shell''. The shell examines each command line it receives from your terminal or workstation, expands the command by substituting actual values for special characters, and then either executes the command itself or calls another program to do so. After the command has completed execution, the shell prompts you for a new command.
Most UNIX systems offer a choice of shells--the Bourne shell (sh) and the C shell (csh) are the most common. The default shell for Hardlink's UNIX systems, and the one described in this manual, is the C shell. Since this manual describes the C shell, you should make sure that is the one you are using. To do so, type
echo $SHELLIf the C shell is reading your commands, the response will be
/bin/csh(The Bourne shell is /bin/sh.) The following sections discuss the shell concepts most needed by novice users.
cat -n stuffcalls the cat program (to ``concatenate'' files). In this case, cat reads the file named ``stuff'' and displays it. The -n flag tells cat to number the lines in the display.
The hyphen that precedes a flag is a special character used to distinguish flags from filenames. In the example above, the hyphen prevents cat from trying to display a file named ``n''. Commands can contain other special characters as well. The shell interprets such characters, and sometimes replaces them with other values, before it passes the command with its flags and arguments to the program that actually executes the command.
Remember that uppercase and lowercase letters are not interchangeable. Thus if you tried to give the cat command by typing CAT, it would fail; there is no program named (uppercase) CAT. Or notice in the echo command shown above that SHELL (and only SHELL) must be all uppercase.
whothe login names of others currently logged in are written to standard output--displayed at your terminal. If you want to have this list placed into a file called ``namelist'', you could use the character > to redirect standard output to namelist, like this:
who > namelistIf you already have a file named namelist, the shell erases its contents, then calls who to write the new information to namelist. If you do not have a file named namelist, the shell creates a new one before it calls the who program.
You can then do what you want with the file namelist--print it, sort its contents, display it with the cat command, or whatever.
To append output to an existing file instead of overwriting it, use the symbol >>. Thus, if you first type
who > namelistand later
who >> namelistThe file namelist will contain two sets of results: the second set is appended to the first instead of destroying it.
Normally, you will not need to redirect standard input, as most commands that can read from standard input also accept an input filename as an argument. However, for commands that normally expect input from your terminal, the character < followed by a filename tells the command to read from that file instead. For example, one way to send mail is to type
mail userand then to type the text of the message from your terminal. If the text of the message is already in a file named letter, you could redirect standard input to send the mail this way:
mail user < letter
Note: The shell performs input and output redirection BEFORE it calls the command you want to execute. This means that files can be accidentally destroyed. For example, the commandsort < myfile > myfiledestroys ``myfile'' because the shell (1) opens myfile for reading and then (2) opens it again for writing. When you open a file for writing, UNIX destroys the old contents of the file. All this happens BEFORE the shell runs the sort program to actually read the file.
who > namelist sort namelistAfterward, you could give another command to get rid of the file namelist.
A pipeline enables you to do all this on a single command line, using the pipe symbol | (vertical bar). When commands are separated by the | symbol, output from the command on the symbol's left side becomes input to the one on the right of it. Thus you could type
who | sortso that the results of the who program are passed to the sort program as input and displayed, by default, on your terminal.
More than one pipe symbol can be used to make a series of commands, the standard output from each becoming the standard input to the next.
Note: If a command is not capable of reading from standard input, it cannot be placed to the right of a pipe symbol.
*
An asterisk matches any number of characters in a filename,
including none. Thus, the command
cat a*would display the file named ``a'', if it exists, as well as any file whose name begins with ``a''. An asterisk will not match a leading period in a file name, but it will match a period in any other position.
?
The question mark matches any single character. Thus
cat ? F?would display all files with single-character names, plus all files that have a two-character name beginning with F. Like the asterisk, a question mark does not match a leading period, but does match a period in any other position.
[ ]
Brackets enclose a set of characters, any one of which may
match a single character at that position. For example,
cat draft[125]displays files draft1, draft2, and draft5 if they exist. Remember that the shell interprets special characters BEFORE it calls the cat program. So there is a difference between
cat draft[125] and cat draft1 draft2 draft5In the first form, the shell considers it a match if ANY of draft1, draft2, or draft5 exist. It builds a cat command that includes only the names of files it finds. If there is no draft2, for example,
cat draft[125]displays draft1 and draft5. However, explicitly giving the command
cat draft1 draft2 draft5displays draft1 and draft 5, but also gives an error message from the cat program: ``draft2: no such file or directory''. If no files begin with ``draft'', then the command
cat draft[125]produces a message from the C shell: ``no match.'' In this case, the shell doesn't even call the cat command.
-
A hyphen used within [ ] denotes a range of characters. For
example,
cat draft[1-9]has the same meaning as
cat draft[123456789]Again, the shell expands this to build a cat command that includes only the filenames that actually exist.
~
A tilde at the beginning of a word expands to the name of your
home directory (the directory in which you are placed when you
log in on UNIX). It is a useful special character if you
changed to some different directory after you logged in, and
want to copy a file to or from your home directory. If you
append another user's login name to the ~ character, it refers
to that user's home directory--useful if you are sharing files
with someone else. For example,
~cssmithmeans ``the home directory of the user whose login name is cssmith''. The usefulness of this notation will become more apparent in the next chapter.
Note: On most UNIX systems, the ~ character has this special meaning to the C shell only, not to the Bourne shell. In shell scripts, which are generally processed by the Bourne shell, use the variable $HOME to specify your own home directory.
set ignoreeofAnother special control character for the C shell is ^z. Whenever you type ^z, it suspends the current program. UNIX responds with the message
stoppedand gives you a new shell prompt. You can later resume the suspended program by giving the fg (foreground) command, or resume it in the background with the bg command. To kill a suspended program, give the command jobs -l to get the program's job number. Then use
kill %job-noto terminate it.
If you fail to kill or resume a suspended process, when you try to log out you will get the message: ``There are suspended jobs''. You can disable ^z entirely under UNIX by making the ``suspend'' character undefined. To do so, type the following command or place it in your .login file:
stty susp ^-You could also use the stty command to redefine the suspend character to something other than ^z.
set prompt=?the shell will expand the question mark to be the first single-character filename it finds in your directory, and that filename will be your prompt. To avoid that problem, use
set prompt=\?
set history=nthen the C shell keeps a record of your most recent n events, where an event is one command line. (That is, an event might include several commands in a pipeline, or several commands that you have typed on a single line.) You can use special characters to reissue the commands without retyping them. Here are some simple ways to do this:
!!
On a line by itself, simply reissues the most recent event.
!cmd
Reissues the most recent event that started with the command
cmd.
!?string
Reissues the most recent event that contained string.
!-n
Reissues the nth previous event. For example, !-1 Reissues
the immediately preceding event, and !-2 reissues the one
before that.
!n
Reissues command line n. To see how previous commands are
numbered, just type:
historyIt will display as many lines as you told set history to keep.
^old^new
Substitutes the string new for the first occurrence of the
string old in the most recent event, and reissues that command
line. Note: This is the real caret character, not a
representation of the Control key.
For example, suppose you want to copy a file from one directory to another, using the cp command, and issued the command
cl my_old_directory/the_file_to_copy my_new_directory/the_new_filenameThen you got the message "cl: Command not found". You can easily correct your mistake by simply typing
^l^p:
!15:s/cot/cat/would reissue event number 15, substituting the string ``cat'' for the string ``cot''. See how the : is used with $ below.
Examples:
!f77This reissues the most recent f77 command--say, after you have corrected a source-file error that caused the previous attempt to abort.
!!:0-2 !-2:$This creates a new command from parts of two that have already been issued: words 0, 1 and 2 from the most recent event, followed by the last word from the event before that.
cd ~colleague;ls
sort verylargefile &The shell will notify you when the background job is finished.
` { } # "Within a program, you should not need to quote special characters to make them ordinary; it is only when the shell interprets your command that such characters are expanded instead of being treated as text.
If you find that you occasionally need to start new copies of the C shell, be sure to use the file .cshrc for commands you want executed every time you start a new C shell. In general, environment variables specified by a setenv command (such as your setenv EDITOR command) should be in .login. Any set commands (such as set history=40) should be in .cshrc so every new copy of the C shell will be able to use them.
You can also put alias commands in .cshrc. For example, if you want to type just h instead of history to display your recently issued commands, put this line in your .cshrc file:
alias h historyKeep in mind that any commands you put into your .cshrc file will not become effective until the next time you start a new copy of the C shell. To make the commands effective immediately, type
source .cshrcThis will execute every command within .cshrc.
If you do not have a .cshrc file, you can copy the file /usr/local/lib/CSHRC instead of making a file from scratch. See chapter 5 to learn how to do this.
Note: The Bourne shell uses just one initialization file--named .profile.
However, if the command is not a built-in command, the shell must call an external program to execute it. But such programs are not all stored in one place: they are organized into hierarchies of directories. To determine where to look for the needed program, the shell examines a variable called PATH. Normally, the path tells the shell to look first in one or more system directories in some particular order, then in your own current directory.
To see what your current path is, give the command:
echo $PATHYou will see a sequence of pathnames, separated by colons. The first pathname on the list is where the shell looks first if the command you gave is not a built-in command; the second pathname is where it looks next if the first path fails, and so on. A null path--a colon alone at the end or the beginning of the list, or a pair of colons-- means your current directory. A period, or dot, as a pathname also means your current directory.
You may never have to do anything to create or change the path variable. But if the shell cannot find a command you want to issue, the reason might be that the command is outside your search path. Also realize that if you give one of your own executable files the same name as a built-in command, your own command might never be executed. The shell will use its own code instead, if its pathname precedes your own pathname.
The next chapter discusses paths and pathnames in more detail.