|
|
|
|
|
|
|
|
|
|
|
The Shell
|
|
|
Whenever you login to a Unix system you are placed in a program called the shell. All of your work is done within the shell. The shell is your interface to the operating system. It acts as a command interpreter; it takes each command and passes it to the operating system. It then displays the results of this operation on your screen. There are several shells in widespread use. The most common ones are described below. |
|
|
|
|
|
Shell
|
Description
|
Bourne shell (sh)
|
Original Unix shell written by Steve Bourne of Bell Labs. Available on all UNIX systems. Does not have the interactive facilites provided by modern shells such as the C shell and Korn shell. The Bourne shell does provide an easy to use language with which you can write shell scripts.
|
C shell (csh)
|
Written at the University of California, Berkley. As it name indicates, it provides a C like language with which to write shell scripts.
|
Korn shell (ksh)
|
Written by David Korn of bell labs. It is now provided as the standard shell on Unix systems. Provides all the features of the C and TC shells together with a shell programming language similar to that of the original Bourne shell.
|
TC Shell (tcsh)
|
Available in the public domain. It provides all the features of the C shell together with EMACS style editing of the command line.
|
Bourne Again Shell (bash)
|
Public domain shell written by the Free Software Foundation under their GNU initiative. Ultimately it is intended to be a full implementation of the IEEE Posix Shell and Tools specification. Widely used within the academic commnity. Provides all the interactive features of the C shell (csh) and the Korn shell (ksh). Its programming language is compatible with the Bourne shell (sh).
|
|
|
|
Your login shell is usually established by the local System Administrator when your userid is created. You can determine your login shell with the command: |
|
|
|
|
|
echo $SHELL |
|
|
|
|
|
Each shell has a default prompt. For the 5 most common shells: |
|
|
|
|
|
$ (dollar sign) - sh, ksh, bash |
|
|
% (percent sign) - csh, tcsh |
|
|
|
|
|
Depending upon the shell, certain features will be available. The table below summarizes the features available with the 5 most common shells. Note: these features will be described in detail later. |
|
|
|
|
|
Processes
|
|
|
Whenever you enter a command at the shell prompt, it invokes a program. While this program is running it is called a process. Your login shell is also a process, created for you upon logging in and existing until you logout. |
|
|
|
|
|
UNIX is a multi-tasking operating system. Any user can have multiple processes running simultaneously, including multiple login sessions. As you do your work within the login shell, each command creates at least one new process while it executes. |
|
|
|
|
|
Process id: every process in a UNIX system has a unique PID - process identifier. |
|
|
|
|
|
ps - displays information about processes. Note that the ps command differs between different UNIX systems - see the local ps man page for details. |
|
|
|
|
|
To see your current shell's processes: |
|
|
|
|
|
% ps |
|
|
PID TTY TIME CMD |
|
|
46450 pts/9 0:00 ps |
|
|
46801 pts/9 0:00 -csh |
|
|
|
|
|
Controlling processes associated with the current shell
|
|
|
Most shells provide sophisticated job control facilities that let you control many running jobs (i.e. processes) at the same time. This is useful if, for example, you are editing a text file and want to interrupt your editing to do something else. With job control, you can suspend the editor, go back to the shell prompt, and start work on something else. When you are finished, you can switch back to the editor and continue as if you hadn't left. |
|
|
|
|
|
Jobs can either be in the foreground or the background. There can be only one job in the foreground at any time. The foreground job has control of the shell with which you interact - it receives input from the keyboard and sends output to the screen. Jobs in the background do not receive input from the terminal, generally running along quietly without the need for interaction (and drawing it to your attention if they do). |
|
|
|
|
|
The foreground job may be suspended, i.e. temporarily stopped, by pressing the Ctrl-Z key. A suspended job can be made to continue running in the foreground or background as needed by typing "fg" or "bg" respectively. Note that suspending a job is very different from interrupting a job (by pressing the interrupt key, usually Ctrl-C); interrupted jobs are killed off permanently and cannot be resumed. |
|
|
|
|
|
Background jobs can also be run directly from the command line, by appending a '&' character to the command line. For example: |
|
|
|
|
|
$ find / -print 1>output 2>errors & |
|
|
[1] 27501 |
|
|
$ |
|
|
|
|
|
Here the [1] returned by the shell represents the job number of the background process, and the 27501 is the PID of the process. To see a list of all the jobs associated with the current shell, type jobs: |
|
|
|
|
|
$ jobs |
|
|
[1]+ Running find / -print 1>output 2>errors & |
|
|
$ |
|
|
|
|
|
Note that if you have more than one job you can refer to the job as %n where n is the job number. So for example fg %3 resumes job number 3 in the foreground. |
|
|
|
|
|
To find out the process ID's of the underlying processes associated with the shell and its jobs, use ps (process show): |
|
|
|
|
|
$ ps |
|
|
PID TTY TIME CMD |
|
|
17717 pts/10 00:00:00 bash |
|
|
27501 pts/10 00:00:01 find |
|
|
27502 pts/10 00:00:00 ps |
|
|
|
|
|
So here the PID of the shell (bash) is 17717, the PID of find is 27501 and the PID of ps is 27502. |
|
|
|
|
|
To terminate a process or job abrubtly, use the kill command. kill allows jobs to referred to in two ways - by their PID or by their job number. So |
|
|
$ kill %1 |
|
|
or |
|
|
$ kill 27501 |
|
|
|
|
|
would terminate the find process. Actually kill only sends the process a signal requesting it shutdown and exit gracefully (the SIGTERM signal), so this may not always work. To force a process to terminate abruptly (and with a higher probability of sucess), use a -9 option (the SIGKILL signal): |
|
|
|
|
|
$ kill -9 27501 |
|
|
|
|
|
kill can be used to send many other types of signals to running processes. For example a -19 option (SIGSTOP) will suspend a running process. To see a list of such signals, run kill -l. |
|
|
|
|
|
|
|
|
|
|
|
Controlling other processes
|
|
|
You can also use ps to show all processes running on the machine (not just the processes in your current shell): |
|
|
|
|
|
$ ps -fae |
|
|
|
|
|
ps -aeH displays a full process hierarchy (including the init process). |
|
|
|
|
|
Many UNIX versions have a system utility called top that provides an interactive way to monitor system activity. Detailed statistics about currently running processes are displayed and constantly refreshed. Processes are displayed in order of CPU utilization. Useful keys in top are: |
|
|
|
|
|
s - set update frequency k - kill process (by PID) |
|
|
u - display processes of one user q - quit |
|
|
|
|
|
On some systems, the utility w is a non-interactive substitute for top. |
|
|
|
|
|
One other useful process control utility that can be found on most UNIX systems is the killall command. You can use killall to kill processes by name instead of PID or job number. So another way to kill off our background find process (along with any another find processes we are running) would be: |
|
|
|
|
|
$ killall find |
|
|
[1]+ Terminated find / -print 1>output 2>errors |
|
|
$ |
|
|
|
|
|
Note that, for obvious security reasons, you can only kill processes that belong to you (unless you are the superuser). |
|
|
|
|
|
Redirection input and output
|
|
|
The output from programs is usually written to the screen, while their input usually comes from the keyboard (if no file arguments are given). In technical terms, we say that processes usually write to standard output (the screen) and take their input from standard input (the keyboard). There is in fact another output channel called standard error, where processes write their error messages; by default error messages are also sent to the screen. |
|
|
|
|
|
To redirect standard output to a file instead of the screen, we use the > operator: |
|
|
|
|
|
$ echo hello |
|
|
hello |
|
|
$ echo hello > output |
|
|
$ cat output |
|
|
hello |
|
|
|
|
|
In this case, the contents of the file output will be destroyed if the file already exists. If instead we want to append the output of the echo command to the file, we can use the >> operator: |
|
|
|
|
|
$ echo bye >> output |
|
|
$ cat output |
|
|
hello |
|
|
bye |
|
|
|
|
|
To capture standard error, prefix the > operator with a 2 (in UNIX the file numbers 0, 1 and 2 are assigned to standard input, standard output and standard error respectively), e.g.: |
|
|
|
|
|
$ cat nonexistent 2>errors |
|
|
$ cat errors |
|
|
cat: nonexistent: No such file or directory |
|
|
$ |
|
|
|
|
|
You can redirect standard error and standard output to two different files: |
|
|
|
|
|
$ find . -print 1>errors 2>files |
|
|
|
|
|
or to the same file: |
|
|
|
|
|
$ find . -print 1>output 2>output or |
|
|
$ find . -print >& output |
|
|
|
|
|
Standard input can also be redirected using the < operator, so that input is read from a file instead of the keyboard: |
|
|
|
|
|
$ cat < output |
|
|
hello |
|
|
bye |
|
|
|
|
|
You can combine input redirection with output redirection, but be careful not to use the same filename in both places. For example: |
|
|
|
|
|
$ cat < output > output |
|
|
|
|
|
will destroy the contents of the file output. This is because the first thing the shell does when it sees the > operator is to create an empty file ready for the output. |
|
|
|
|
|
One last point to note is that we can pass standard output to system utilities that require filenames as "-": |
|
|
|
|
|
$ cat package.tar.gz | gzip -d | tar tvf - |
|
|
|
|
|
Here the output of the gzip -d command is used as the input file to the tar command. |
|
|
|
|
|
Pipes
|
|
|
The pipe ('|') operator is used to create concurrently executing processes that pass data directly to one another. It is useful for combining system utilities to perform more complex functions. For example: |
|
|
|
|
|
$ cat hello.txt | sort | uniq |
|
|
|
|
|
creates three processes (corresponding to cat, sort and uniq) which execute concurrently. As they execute, the output of the who process is passed on to the sort process which is in turn passed on to the uniq process. uniq displays its output on the screen (a sorted list of users with duplicate lines removed). Similarly: |
|
|
|
|
|
$ cat hello.txt | grep "dog" | grep -v "cat" |
|
|
|
|
|
finds all lines in hello.txt that contain the string "dog" but do not contain the string "cat". |
|
|
|
|
|
Filters
|
|
|
A filter is a command that processes an input stream of data to produce an output stream of data. Command lines which use a filter will include a pipes to connect it to the stdout of one process and the stdin of another process. |
|
|
|
|
|
For example, the command line below takes the output of "who" and sorts it. The sorted output is then passed to the lp command for printing. In this example, sort is a filter. |
|
|
|
|
|
who | sort | lp |
|
|
|
|
|
Both filters and pipes demonstrate a basic UNIX principle: Expect the output of every program to become the input of another, yet unknown, program to combine simple tools to perform complex tasks. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|