Table of Contents Previous Chapter

CHAPTER 4 The Shell Program

After you log in, the shell program, or shell, is activated. A shell is a user interface program through which you can communicate with UNIX. The shell displays the prompt $, which is changeable (see "Customizing the Session: Defining the Shell Environment" on page 30), as a signal that it is ready to receive your UNIX commands. It interprets and executes the UNIX command that you type, and when done, gives you the next prompt. The default shell for SLAC UNIX accounts is either the C shell, csh, for older accounts; or an extended version of the C shell, tcsh, for accounts created more recently. Both these shells use a syntax based on that of the C programming language (hence their names). The features of tcsh are a superset of those of csh. One of the most popular additional features in tcsh is an intuitive (and VMS-like) interface for recalling and editing previously-issued command (see the section "Keeping Command History" on page 37). You can obtain full documentation about the C shell with man csh; for the additional features of tcsh, use the command man tcsh. (For more information on the man command, see "More About the Manual" on page 10.)

Other shells available at SLAC include the Bourne shell, the Korn shell (ksh) and the Bourne Again shell (bash). The latter two are each upwardly compatible extensions of the Bourne shell, which was the original UNIX shell; all three share a syntax that is somewhat different from that of csh and tcsh. On most systems, the Bourne shell is synonymous with the "default shell", and is referred to simply as "sh"; however, IBM's version of UNIX, AIX, uses the Korn shell as the default, and this is assumed in all the IBM documentation. Moreover, starting in Version 4 of AIX, the command name "sh" invokes the Korn rather than the Bourne shell. In order to invoke the Bourne shell on an AIX 4 system, you must use the "bsh" command (note that the bsh command does not exist in all versions of UNIX).

Although shells normally read one command at a time from your terminal, they can also read commands from a file. Such a file is called a shell script, and may include a variety of control structures, such as loops and if-then-else blocks. Thus, in addition to a user interface, the shell also provides a simple programming language. For more information about the programming features of a particular shell, see the appropriate man page.

Unless otherwise noted, the syntax and features of tcsh will be assumed throughout the remainder of this chapter.

Changing Shell Programs

During a work session you may from time to time start a new shell. This may be done explicitly, for example to run a script written for a different shell language, or implicitly when you use certain commands (e.g., the script command, described in "Keeping Command History" on page 37). A change in the default prompt may indicate that you have invoked a new shell. Your login shell is the shell that is automatically invoked when you first login to a UNIX system. To leave a shell, use the exit command or press CTRL-d. This will return you to the previous shell or perform a logout if you are in your login shell

Shell programs provide methods to initialize your environment when they detect that they are being invoked as login shells, but these methods differ. The only shells supported by SCS as login shells are tcsh and csh; the former is recommended, and the latter is supported primarily for backward compatibility. To change your login shell you must run the chsh command on host unixhub (the change may take an hour or longer to actually go into effect):

-----------------------------------------------------------------------------------------------------
ilse@janus $ rlogin unixhub                                          Log in to UNIX host unixhub.      
Password:                                                            Type your password.               
Last login: Tue Aug 24 08:44:25 from JANUS.SLAC.Stanf                                                  
SunOS Release 4.1.2 (SERVER) #1: Tue Feb 23 18:52:48 PST 1993                                          
WARNING: Unauthorized access to this computer system is prohibited.                                    
Violators are subject to criminal and civil penalties.                                                 
ilse@unixhub $ chsh                                                  Change shell command.             
Changing NIS login shell for ilse on unixhub.                                                          
Old shell: /bin/csh                                                                                    
New shell: /bin/tcsh                                                 Type full pathname of new shell.  
Password:                                                            Type your password.               
                                                                                                       
-----------------------------------------------------------------------------------------------------
Assuming you're switching between the csh and tcsh shells, you must also modify the .cshrc file in your home directory once the above change has gone into effect (See the next section for more information about the .cshrc file). Open this file in a text editor (see "Editors" on page 39 for information about text editors) and look for the invocation of SLAC's environ shell script, i.e., a line near the beginning of the file that looks something like this:

eval `/usr/local/bin/environ /bin/csh -i${?prompt} -e emacs:vi`

The string "/bin/csh" must be changed to correspond to your new login shell; e.g., if you've just changed to the tcsh shell, change this line to:

eval `/usr/local/bin/environ /bin/tcsh -i${?prompt} -e emacs:vi`

Save the file and exit the editor, then logout and login again.

WARNING!! Although new accounts are set up with additional dot files (e.g., .profile) that are used by some other shells at login time, these are intended as examples only and are not supported by SCS. Note also that the full path for the Bourne Again shell is /usr/local/bin/bash, not /bin/bash.

Customizing the Session: Defining the Shell Environment

UNIX allows you to customize your interaction with the shell program in many ways. You can create abbreviations for files or directories or lengthy commands; determine the directories the shell uses to search for the programs and commands to run; create the prompt the shell uses when it interacts with you; and have UNIX set your terminal type every time you login, without having to type the command yourself.

Similar to program variables (place holders of information), shell and environment variables store values that the shell uses in executing your commands. Shell variables help determine how the shell program interacts with you. You can create your own shell variables and assign them values with the set command, and you can insert the variable value in a command line by prefixing the variable name with $.

--------------------------------------------------------------------------------------------
$ set docdir=/usr/local/doc                                                                    
                             Sets the variable docdir to /usr/local/doc.  That is, docdir      
                             becomes an abbreviation for /usr/local/doc.                       
$ echo $docdir               Shows the value assigned to docdir.                               
/usr/local/doc                                                                                 
$ cd $docdir                 The current working directory changes to                          
                             /usr/local/doc.                                                   
$ unset docdir               Removes the shell variable docdir.  Now, you can no longer use    
                             $docdir to refer to the directory                                 
                             /usr/local/doc.                                                   
--------------------------------------------------------------------------------------------
The procedure shown in the preceding sample session sets the shell variable for use during your present interaction with the current shell. For example, if you used the script command, a new shell would begin, and this shell variable would no longer be set. Even if you used only the login shell, the next time you login you would have to repeat the procedure of setting the shell variable.

If you want to use the shell variable every time you interact with the C shell, use a text editor to add the command line to the .cshrc file. (See "Editors" on page 39 for more information on editors.) The .cshrc is the C Shell Run Commands file, a dot file in your home directory. (See "Working With Files" on page 15 for more information on dot files.) Every new UNIX account gets a .cshrc file that sets a number of defaults such as the architecture of the host machine and via SLAC's environ shell script. The environ script is invoked via an eval command that looks like this:

eval `/usr/local/bin/environ /bin/csh -i${?prompt} -e emacs:vi`

Changes should normally be added after the invocation of the environ script.

Use the set command to see shell variables and their values.

------------------------------------------------------------------------------------
$ set               Without argument, set displays shell variables and their values.  
argv ()                                                                               
cwd     /u/sf/ilse                                                                    
term    vt100                                                                         
history 50                                                                            
------------------------------------------------------------------------------------
A few shell variables have special meaning to the shell program. By assigning values to these variables, you customize the manner in which the shell executes your commands. The one covered here is the path variable. path, as well as others such as prompt, history, and term, are set in your default .cshrc file, and, of course, you can change them if you like.

About Path and Environment Variables

One of the most important shell variables is the path shell variable. The value for the path shell variable is a list of directories. This list of directories is called your search path. UNIX searches these directories when it looks for a program or command specified on the command line. If a program is in your search path, you can just type the name of the program; you don't have to type its absolute or relative pathname. Suppose your search path is:

/u/<gg>/<userid>/bin /usr/local/bin /usr/afsws/bin /usr/ucb /bin /usr/bin

where"/u/<gg>/<userid>/bin" identifies your personal bin directory. Whenever you type a program name or command, the shell looks first in your bin directory, second in the directory /usr/local/bin, third in the directory /usr/afsws/bin, and so on. It keeps looking until it either finds the program or command with that name or finishes looking through all the directories in your search path.

------------------------------------------------------------------------
$ joes_program                    Let's say you execute                   
                                  joes_program frequently.                
joes_program:  command not found  The command is not in the search path.  
$ set path=($path /joe/bin)       Adds the directory where                
                                  joes_program is located to the search   
                                  path for that particular session only.  
------------------------------------------------------------------------
The procedure in the sample session above adds a directory to your search path for your present session with the shell. Notice the following features of the above set path command:

Parentheses must surround the value to the right of the equals sign because it is a blank-separated list of words rather than a single word or quoted string.
The current value of your path shell variable can be referenced on the right of the equals sign; this makes it easy to add directories to the end (as in this example) or the beginning of your search path.
Your search path may include a period to represent your current working directory. Though this is sometimes convenient, it presents a significant security risk via so-called "trojan horse" attacks, particularly when the period is at the beginning of the search path.

WARNING!! At present, SLAC's environ script inserts a period at the beginning of your search path; however this policy is currently under review and may be changed in the near future.
If there is a period early in your search path, please consider moving it to the very end or, better yet, removing it altogether. It is always possible to execute a command in your current directory simply by prefixing it with "./".

Removing a directory from your path shell variable is a little less straightforward than adding one. Here's an example that will safely remove the period representing your current directory from anywhere in your search path (note that the blanks in this example are significant):

set path=( `echo " $path " | /bin/sed -e "s% . % %g"` )

If you find that you frequently use a program or command not included in your default search path, you can edit or add a "set path=" command in your .cshrc file.

After you add or modify command lines in the .cshrc file, the changes will be in effect for all subsequently started shells. However, neither your currently running shell, nor any of its ancestors will automatically see the changes. To invoke the commands added to your .cshrc file in your current shell, use the source command, as shown in the following sample session.

---------------------------------------------------------------------------
$ source .cshrc  Now the commands in the .cshrc file run, so the shell vari  
                 ables are set as you specified in the .cshrc file.          
---------------------------------------------------------------------------
Environment variables are similar to shell variables, but other programs besides the shell use their values. Typically, these environment variable names are all uppercase. An example of an environment variable is PRINTER. The value associated with this environment variable determines the default printer. At SLAC a variety of printers are available to UNIX users. They are listed in the file /etc/qconfig (RS/6000 users only) or /etc/printcap (all other UNIX users). The following sample printer description from the former file shows an HP printer located in the computer building:

...
* Computer Building, 1st Floor, George Maclin
hpcgb1a:
host = lpd01
s_statfilter = /usr/lpd/bsdshort
l_statfilter = /usr/lpd/bsdlong
rq = hpcgb1a
device = rlp218
...

The same printer in the latter file appears as:

...
hpcgb1a|Computer Building, 1st Floor, George Maclin:\
:sh:\
:mx#0:\
:rm=lpd01:\
:lp=:\
:sd=/usr/spool/lp/hpcgb1a:\
:rp=hpcgb1a:
...

For more information about printing, see "Printing" on page 43.

The commands to set, unset, and look at environment variables are slightly different than those used with shell variables. As for shell variables, command lines to set environment variables can be added to your .cshrc files.


-----------------------------------------------------------------------------
$ setenv PRINTER hpcgb1a                                                       
                          Sets environment variable PRINTER to hpcgb1a.        
$ unsetenv PRINTER        The environment variable PRINTER is no longer set.   
$ printenv                Prints environment variables and their values.       
HOME=/u/sf/ilse                                                                
SHELL=/bin/tcsh                                                                
TERM=vt100                                                                     
USER=ilse                                                                      
...                                                                            
-----------------------------------------------------------------------------

Creating Shorthand Names for Commands: Aliases

Aliases allow you to create shorthand names for frequently used or lengthy command lines. When the alias

appears in the command line that the shell reads, its text is replaced by the definition of the alias. Use the alias command to create aliases and the unalias command to delete aliases.

-----------------------------------------------------------------------------
$ alias prt lpr -Phpcgb1a  prt will be shorthand for printing on the hpcgb1a   
                           printer.                                            
$ alias prt                Shows commands associated with prt.                 
lpr -Phpcgb1a                                                                  
$ alias                    By itself, alias displays the aliases you set up.   
ll      ls -l !*                                                               
ls      (ls -F)                                                                
prt lpr -Phpcgb1a                                                              
...                                                                            
                                                                               
$ prt unix.doc             Prints file unix.doc on the hpcgb1a printer.        
$ unalias prt              Removes the alias prt.                              
-----------------------------------------------------------------------------
This sample session sets up the alias for your use during the present interaction with the current shell. However, if you know you want to use the alias in later interactions with the shell program, you should add the command line to the .cshrc file in your home directory.

Note: The example above shows another way to produce the same effect as the command setenv PRINTER. The environment variable is discussed in "About Path and Environment Variables" on page 32

Redirecting Input/Output

Normally, UNIX commands needing user input require you to type the input at the keyboard. Most UNIX commands show you the output of the command by displaying it on your terminal screen. The keyboard is the standard input and the terminal is the standard output. But often you might like to store the lengthy output of a command in a file or cause the input for a command to come from a specific file. The shell provides a means for redirecting where a command sends its output or receives its input. The characters <, > and >> are used to redirect input and output.

-----------------------------------------------------------------------------------------------------
$ who                                              who shows who is logged on to the system            
raines  ttyp0  Aug 20 09:08  (CGIBM1.SLAC.Stan)                                                        
ohnishi ttyp1  Aug 20 09:17  (134.79.128.89:0.)                                                        
meb     ttyp3  Aug 20 08:15  (sisyphus:0.0)                                                            
$ who > who.doc                                 Places the output of the who command into           
                                                   the file who.doc. If the file already exists, its   
                                                   contents are replaced by the output of the who      
                                                   command.  If the file does not already exist, it    
                                                   is created.                                         
$ sort who.doc                                     sort re-orders the contents of file who.doc         
                                                   alphabetically, and writes the result to standard   
                                                   output.                                             
meb      ttyp3   Aug 20 08:15  (sisyphus:0.0)                                                          
ohnishi  ttyp1   Aug 20 09:17  (134.79.128.89:0.)                                                      
raines   ttyp0   Aug 20 09:08  (CGIBM1.SLAC.Stan)                                                      
-----------------------------------------------------------------------------------------------------
WARNING!! In the sample session above, the output of who was placed in the who.doc file. When you redirect the output of a command, you can either make up a new file to store the output or use a file that already exists. If you use a file that already exists, however, the contents of that file will be replaced by the redirected output. To avoid accidentally overwriting an existing file with the > character, use a text editor to put the command set noclobber in your .cshrc file.
-----------------------------------------------------------------------
$ who >> info.doc  Append the output of the who command to the     
                         end of file info.doc.  The contents of this     
                         file remain intact with the output of the who   
                         command attached at the end.                    
-----------------------------------------------------------------------
The tr command in the following example only reads standard input and writes standard output unlike some commands which allow you to specify an alternative input and/or output file.

----------------------------------------------------------------------------------------
$ tr a-z A-Z < Text > Text.upper  Translates all lowercase characters in the file   
                                        Text to uppercase in the file Text.upper.         
----------------------------------------------------------------------------------------
The cat command allows you to concatenate files together. It simply copies the files you specify as arguments to its standard output, which defaults to your terminal screen. With the > character, however, you can redirect the output from the screen to another file. Note the warning in the paragraph above.

--------------------------------------------------------------------------------------
$ cat sec1.doc sec2.doc > unixbook   Strings together sec1.doc and sec2.doc.          
                                        Redirects the output of the cat command to the   
                                        file unixbook.                                   
--------------------------------------------------------------------------------------
Often it is convenient to make the output of one command become the input of another command. The UNIX shell provides a means of connecting the output and input of two commands via a mechanism called a pipe. The pipe character (|) is placed between two commands when the first command's output should be the input of the second.

-------------------------------------------------------------------------------------------
$ ls -l /bin  | more                             Lists the files in directory /bin (the com  
                                                 mand ls -l /bin), one screenful at a time   
                                                 (the command more).                         
total 2722                                                                                   
-rwxr-xr-x  2 root        4008 Jul 21  1992 [*                                               
-r-xr-xr-x  1 root        9080 Jul 21  1992 ar*                                              
-r-xr-xr-x  1 root      122880 Jul 21  1992 as*                                              
...                                                                                          
-------------------------------------------------------------------------------------------
The characters in the command line that redirect input/output (<, >, and >>) and pipe commands (|) are not part of the commands themselves. Rather, they are special characters, which hold special meaning to the shell. That is, the commands themselves know nothing about the <, >, and | characters, but the shell recognizes them and provides the mechanism by which this redirection takes place.

Referring to Groups of Files

The shell recognizes other special characters besides those that redirect input/output and serve as pipes between commands. The most common are those associated with filenames. When included in a file's name, these characters allow you to specify groups of files more easily. For more information about using these characters, give the command man csh.

TABLE 4. Special Characters Used with Filenames 
-----------------------------------------------------------------------------------------------------
The Character  What It Means                                                                           
-----------------------------------------------------------------------------------------------------
*              Refers to any string of zero or more characters.                                        
?              Refers to any single character.                                                         
~              Has special meaning when associated with a username as in ~smith. In these              
               cases, this refers to the user smith's home directory. Thus, ~smith/.login              
               refers to the file .login in smith's home directory. By itself, ~ refers to your home   
               directory.                                                                              
[ ]            Indicates any single character of the ones in the brackets.                             
-----------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
$ ls                                           Lists all files in the working directory.                
Makefile    main.c    queues.h  sub.c                                                                   
globals.h  queues.c  sim.h     test1                                                                    
$ ls *.c                                       Lists all files ending with .c.                          
main.c     queues.c   sub.c                                                                             
                                                                                                        
$ ls s*.c                                      Lists all files beginning with s and ending with .c.     
sub.c                                                                                                   
$ ls test?                                     Lists all files beginning with test, ending in any       
                                               single character.                                        
test1                                                                                                   
$ ls *.[ch]                                    Lists all the files, ending in .c or .h.                 
globals.h       queues.c        sim.h                                                                   
main.c          queues.h        sub.c                                                                   
$ ls ~smith                                    Lists all files in the home directory for smith.         
Work  mbox  bin                                                                                         
--------------------------------------------------------------------------------------------------

Name Completion

A very useful feature of tcsh is name completion, that is, the ability of the shell to complete the typing of a name on the command line, given a unique abbreviation. This works for command names, filenames, references to shell and environment variable names (i.e., when the name follows a $-sign), and the ~username convention. It is triggered by typing part of the name and pressing the TAB key. If the part of the name you type does not uniquely identify a complete name within the appropriate class of names, any additional unambiguous characters are added to what you typed and the terminal bell is rung. At this point you can type CTRL-d to display a list of matching names. You can then type a few more characters and try pressing TAB again. There are a number of ways in which the behavior of this feature can be modified (the above behavior is the default); for details, enter "man tcsh" .

The C shell has a similar but more limited feature. It only works with filenames and the ~username convention, is triggered by the ESC key rather than the TAB key, and is disabled by default (to enable it, define the special shell variable "filec" to any value in your .cshrc file, e.g., by adding a line like "set filec=on").

Keeping Command History

The shell has a mechanism that allows you to review the commands you entered most recently. The number of commands you can review is determined by the value of the history shell variable which is 50 as set in your default .cshrc file. You can then use a variety of commands to review and repeat your saved commands:

-----------------------------------------------------------------------------------------
$ set history=5         Sets number of commands for UNIX to save at n (in this case, 5).   
$ history               Displays the previous 5 commands, as set in the step above.        
15 who                                                                                     
16 finger smith                                                                            
17 talk smith                                                                              
18 cd ~                                                                                    
19 rm who.doc * [.1in]                                                                     
$ !!                    Repeats the immediately preceding command.                         
history                                                                                    
16 finger smith                                                                            
17   ...                                                                                   
:                                                                                          
$ !finger               Repeats most recent command starting with string finger.           
finger smith                                                                               
$ !16                   Repeats command 16.                                                
finger smith                                                                               
                                                                                           
-----------------------------------------------------------------------------------------
When using tcsh (but not csh) you can scroll through your command history using the up- and down-arrow keys, position the cursor within a command using the left- and right-arrow keys, and edit the command before reexecuting it.

Sometimes you may want to save your commands and the shell's response in a file. That way you can see or print the information later. You may want to record the running of a specific program and inspect this session later. The script command saves the record of your interaction with the shell in a file named typescript in the working directory. You must give the script command before you start the process you wish to record. You can specify different file names if desired by typing script filename; type man script at the shell prompt for more infor

mation. To signal the end of the recording, type the command exit. At that point, you can look at the typescript file by typing more typescript at the prompt.

-----------------------------------------------------------------------------
                                                                               
$ script                                     Saves all commands and shell      
                                             responses that follow.            
Script started, file is typescript                                             
csh> testprog                                                               
What is the result of 3+4? 7                                                   
Correct!                                                                       
csh> exit                                 Ends the recording.               
csh> Script done, file is typescript                                        
$ more typescript                            Displays the commands and shell   
                                             responses just saved.             
Script started on Tue Nov 06 23:57:06 1990                                     
csh> testprog                                                               
What is the result of 3+4? 7                                                   
Correct!                                                                       
csh> exit                                                                   
script done on Tue Nov 06 23:57:06 1990                                        
$                                                                              
-----------------------------------------------------------------------------
 
Table of Contents Next Chapter