previous contents up next

Unix for Advanced Users

3. The Shell

3.2. What the shell can do for you

3.2.1. Interactive vs. scripting use

The shell not only allows the user an interactive login session but can be used non-interactively. Toward this end, the shell supports a simple language definition for creating shell script files. These files permit the user to non-interactively submit commands as though they were from the command line. This provides the same sort of functionality as DOS batch files or Netware login scripts with much more power and flexibility. Scripts can be used to generate very complex command sequences which can be an incredible time saving device when repeating a large sequence of commands with changing arguments.

3.2.2. Aliasing

The concept of aliasing is really pretty simple. Basically aliasing allows you to set one command to run something else. Say for example you want to get a long list of files with one keystroke. You can alias the l key to be ls -l.

The Bourne style syntax for aliases is

alias name="command"

The C-shell syntax for aliases is

alias name "command"

The quotation marks can be omitted, but are needed for aliases that contain spaces. For instance, you could write

alias l=ls,

but not

alias l=ls -al

The latter would not work. To obtain the right effect, you would need to type

alias l="ls -al"

or

alias l "ls -al"

in the C-shell.

3.2.3. Job control

The shell is capable of running programs in the background. Tasks which are non-interactive (do not require keyboard input or display output) can run in the background as separate tasks. This permits the user to continue working with other interactive programs. Examples of this are printing or sorting files.

You can put a running job into background by using CTRL-z.

The shell permits you to control these "jobs" - pushing them to the background - moving them to the foreground. All shells (except the original Bourne shell) permit some form of job control.

jobs is the command to list the jobs running as background processes of your current shell. It shows a job number in brackets, along with some information about the state of a given job (Running, Stopped, or Terminated). To see the process ID number of the jobs you type jobs -l

Shell commands that refer to jobs always use a percentage sign (%) before a job number in arguments. The most common example is fg, which brings a job into the foreground: its syntax is fg %job_number. Likewise, the command to take a stopped job and start it running again in the background, bg, is run as bg %job_number. kill can be used with a single job argument, as in kill %1 or with several, as in kill %1 %3 %5 %13.

3.2.4. I/O redirection

There are three standard devices supported by the Unix shell. These devices may be redirected to another device or file. The three standard devices are:

Programs designed to use the standard input device (keyboard) and standard output device (display) can have their input and output devices redirected to other devices. For example, a program which generally reads from the keyboard can be redirected to read from a file instead. A program which writes its output to the display can be instructed to redirect its output to the printer or a file.

the symbol > changes the standard output device

the symbol < changes the standard input device

For instance, you could type:

egrep 'SECURITY|WARNING' /var/log/messages > bad_stuff

to save the most serious messages from your syslog to a file. If you later wanted to append contents to that file without destroying the old contents, you could use the >> operator:

egrep 'EMERGENCY|CATASTROPHIC' /var/log/messages >> bad_stuff.

The idiom > filename_of_choice starts a new file with zero length, like touch, but also can destroy an existing file. In the C-shell you can get a warning when such a situation arises by typing

set noclobber

To override the noclobber setting, you can use an exclamation point after the redirect like this: >!

Each of the above examples concern themselves with the redirection of standard out. It is also possible to redirect standard error as well. Bourne constructs will redirect standard error if you place a 2 before the >. For example:

find / -name '*important*' 2> /dev/null

will look for files you can reach on the system whose names match a pattern, while sending error messages about directories you are not permitted to read to oblivion.

Both standard error and standard out can be redirected to a single location. Let's say you want to debug your X-configuration on your new Linux box. The Bourne style shell will use the following command to send standard out and standard error to a file called "debug-info":

startx > debug-info 2>&1

The 2>&1 construction says that standard error (2) is to follow the path that standard out (1) takes.

The same command for C-style shells looks like this:

startx >& debug-info

Redirecting a command's input is less common, but useful for some commands. You can mail bob@sun.com < my_document to send a pre-composed message in a file called my_document.

3.2.5. Command History

History allows you to get a list of the commands that you previously executed. Executed commands get saved to a file that can be searched later. This is helpful for repeating commands with a long hairy syntax. This can also be helpful for trying to detect mistakes you might have made.

All shells except the standard Bourne shell have a built-in command called history that takes no arguments and prints out the last several commands you typed during the current shell session. The specific number of commands shown is configurable, like most shell attributes. For bash and ksh the history size is set by the environment variable HISTSIZE. ksh saves the command history to a file called .sh_history between logins. bash permits you to determine how many commands you save between logins with the environment variable HISTFILESIZE.

For csh and tcsh the history size is set by the environment variable called history and the saved history between logins is determined by the variable savehist.

All but standard Bourne shell and ksh allow you to execute commands in your history either by number or by string. To get this feature you precede either with an exclamation point (!). So, !42 executes the forty-second command in your history; !vi will execute your last vi command, effectively reopening the last file you edited.

A nice feature of bash permits you to use the up and down arrow keys to scroll backwards and forwards in your history, reviewing old commands and, if you choose, editing them and running them anew. You can even do Emacs-style i-searches backwards and forwards, using Ctrl-r and Ctrl-s key sequences.

3.2.6. File/Command Name Completion

Filename completion permits you to type in a partial file name, and then by pressing a key the shell attempts to complete the name of the file for you. If no file exists that begins with the characters you typed, the shell will beep at you, and will not complete the name. If more than one file begins with the characters you typed, the shell will complete the name up to the point where the names differ. Then you can type additional letters to zero-in on the file you want.

The Bourne shell itself doesn't offer this feature although bash does. In bash, you can type in a partial filename and hit the Tab key to complete it. The completion stops, sending a beep to the terminal, once an ambiguity is encountered. For instance, if you have a file called main.c and a directory called mail, hitting Tab after the partial command more m will cause the shell to fill the phrase in to more mai, then beep and show you the choices main.c and mail. You can then type in an n and hit Tab again to complete unambiguously the filename main.c. Alternately, you could type in l, which the shell would complete to mail, giving you a complete listing of that directory if you hit Tab a second time.

The C-shell offers filename completion but you must either type set filec or have it sitting in your .cshrc file. tcsh has filename completion by default and doesn't require this line. Unlike bash, the C-shell uses the escape key to complete filenames. If the filename is not completed, you need to enter more characters until the filename can be uniquely identified. To get a list of all possible completions, type CTRL-D.

The Korn Shell offers two different styles of filename completion depending on how the EDITOR environment variable is set. If $EDITOR is equal to emacs then completion happens by pressing the escape key twice. As above, if the filename is not completed, you need to enter more characters so the filename can be uniquely identified. If $EDITOR is set to vi then the completion code is escape followed by backslash (\). To list all possible file options in this mode, you press escape followed by the equal sign (=).

previous contents up next