[Next] [Previous] [Up] [Top] [Contents] [Index]
Chapter 5: Important UNIX Concepts
A program is an executable file. A program is invoked by entering its filename (which is the command associated with the executable), often followed by options, arguments, and/or parameters on the command line. The shell allows three types of commands:
The first two command types may include standard UNIX utilities, commercial products, and user-written programs. All the shells allow both interactive command entry in which the commands are typed at the keyboard and executed one by one, and scripted entry in which commands are put in a file, called a shell script, and executed sequentially when the script is run. See section 4.4 for a brief discussion of the uses of shell scripts and how to execute them.
Shells execute commands by means of processes. A process is an instance of a program in execution. A process can interact with the kernel by invoking a well defined set of system calls. The system calls instruct the kernel to perform particular operations for the calling program and they can exchange data between the kernel and the process. For example, a process can use system calls to create new processes and terminate running processes.
When a terminal session begins, the operating system starts a single parent process. Creating a new process from an existing process is called forking. This new process is called a child process or subprocess. Each process has a unique process identification number (PID). A subprocess can fork another process and become a parent. A process which is not receiving input from the terminal, either running or stopped, is said to be in the background (see section 5.5). The ps command can be used to print the status of active processes. See the man pages for information about its options.
When you give the shell a command associated with a compiled executable or shell script, the shell creates, or forks, a new process called a subshell. The new process runs the system call exec which invokes yet another program to execute the command in place of the current process (the subshell). Unless the subprocess runs in the background, the parent process remains dormant until its subprocess completes or is stopped. Then control returns to the parent.
To execute most built-in commands, the shell forks a subshell which executes the command directly (no exec system call). For the built-in commands cd, set, alias and source, the current shell executes the command; no subshell is forked. You can, however, cause the shell to fork a process by enclosing the command in parentheses. The following example illustrates this (use of the semicolon is described in section 2.5; and the commands cd (change directory)and pwd (print working directory) are described in section 6.5):
% cd /dir1; pwd displays /dir1 (no subshell is forked)
% (cd /dir2; pwd) due to the parentheses, a subshell is forked, then the commands are issued; displays /dir2. Control then returns to the parent process.
% pwd displays /dir1 since the current process was unaffected by the previous command line.
Most built-in commands exist in all shells, but there may be differences regarding arguments, options, or output format between the shell-specific versions of each command. Some commands for a given shell are not available on all platforms. Refer to a UNIX text for lists of built-in commands.
You do not need to distinguish between built-in and other commands to execute them. However in order to find help in the man pages, you do need to know which is which. Help on shell commands is usually found under the shell name, for example under man tcsh or man bash. Some platforms provide man pages for built-in commands, however in general you may find it easier to look in a reference book! Help on other commands is found directly under man command.
When the shell receives a command, it interprets it in a series of three (for Bourne shell family) or four (for C shell family) passes. Naturally, if the command is an alias (see section 9.3), it requires an additional pass up front for substitution.
! character, and replaces it with the previous command (see section 5.3 for information on command recall).
$ character in order to replace variable names with their values (see section 9.1).
There are ways to prevent interpretation of special characters in each of these passes. Preceding a character with a backslash (\) works for all special characters; wildcards can be enclosed in single or double quotes; variables can be enclosed in single quotes; and whitespace is ignored if the argument containing the whitespace is enclosed in single or double quotes.
To illustrate the operations that take place in each pass, the following table presents a series of three examples using the echo command and the same string, first in single quotes, then double quotes, and finally with no quotes. The echo command writes the string to standard output. Assume that the files that match q* are qq and qqq, and the value of the variable a is foo.
Command --> | | | |
After first pass[17], only wildcards are interpreted. | (no wildcard expansion due to quotes) | (no wildcard expansion due to quotes) | (unquoted wildcard is expanded) |
After second pass, unquoted or double quoted variables are replaced by their values. | (no variable replacement due to quotes) | (double-quoted variable | (unquoted variable |
After final pass, command string is broken up according to whitespace. The separate elements are listed vertically. | (string treated as one argument due to quotes) | (string treated as one aregument due to double quotes) | (no quotes; each argument treated separately) |
When you type in the original command, the system returns the string: | | | |