-->
Previous Table of Contents Next


Understanding Command Groups, Subshells, and Other Commands

You terminate a simple command with a carriage return. If you want to place more than one command on the command line before pressing <Return>, you can delimit individual commands with a semicolon (;), thus forming a group of commands. When the shell parses the command line, it treats the semicolon as an end-of-line character. If you type the following string, the shell executes each command sequentially as though you had typed each on a line by itself:


command-1; command-2; command-3

For example, you can enter clear;ls to clear your screen and display a directory listing.

Command Groups

If you want to redirect input or output to all the commands as a group, you can do so by making the command line a command group. A command group is defined as any number of commands enclosed in braces ({}). For example, the following command string directs the output of both commands to the file named output-file:


{command-1; command-2}  >  output-file

Any form of redirection can also be used. The output of a command group can be piped, as in the following example:


{command-1; command-2}  |  command-3

In this case, the output of command-1 is fed into the pipe, the output of command-2 is then fed into the same pipe, and command-3 sees just one stream of data.


NOTE:  Commands executed in a command group run in the current shell. That means that they may modify the environment or change directories.

Subshells

When you run a series of commands as a command group, those commands run in the current shell. If one of the commands modifies the environment or changes directory, the changes are in effect when the command group finishes running. To avoid this problem, run a command group in a subshell.

A subshell is a clone of the present shell, but because child processes can’t modify the environment of their parent process, all commands run in a subshell have no effect on the environment when the command group finishes. To run a command group in a subshell, replace the braces with parentheses. The command-group example in the preceding section then becomes the following:


(command-1; command-2)  |  command-3

Only command-3 runs in the current shell, but the output of the subshell is piped into the standard input of command-3.

Doing Background Processing

Because Linux is a multitasking operating system, you can run commands in the background in several ways. The simplest form of background processing allows you to run a command concurrently with a command in the foreground. Other methods place commands deeper and deeper in the background.

Arranging for Processes to Run in the Background

The shell allows you to start one process and, before the first one completes, start another. When you do this, you put the first process in the background. You put a process in the background by using the ampersand (&) character as the last character on the line containing the command you want to run in the background. Consider the following command:


sort  sales  >  sales.sorted  &

If you enter this command, you see a number on-screen. This number is the process ID (PID) number for the process you put in the background. The PID is the operating system’s way of identifying that process.

Normally when you run a command, the shell suspends operation until the command is complete. If you append the ampersand to the end of a command string, the command string runs concurrently with the shell. By placing the ampersand after a command string, the shell resumes operation as soon as the background command is launched. Unless you use I/O redirection with the background command, the background command and the present shell expect input from and produce output to your terminal. Unless your background command takes care of I/O itself, the proper syntax for background processing is as follows:


command-string   [input-file]   output-file &

For example, to copy a collection of files whose names end with the characters .txt to a subdirectory named oldstuff and, without waiting for that process to finish, print a sorted list of the data in all files with names that begin with sales, use the following two commands:


cp  *.txt  oldstuff  &

cat  sales*  |  sort  |  lp


TIP:  Put jobs in the background when you don’t want to wait for one program to finish before starting another. You can also put jobs in the background when you have a collection of tasks in which at least one can run on its own. Start that one and put it in the background.

You can also use the virtual terminals offered by Linux to execute a command and then log in to another terminal.


Because the background process is a child of your shell, it’s automatically killed when you log out. All child processes are killed when their parent dies.

Using the nohup Command

To place a command deeper in the background than the & operator allows, use the nohup command (which stands for no hang up). The nohup command takes as its arguments a command string. However, nohup must be used with the & operator if you want the command to actually be placed in the background. If a command is run with nohup in the foreground, the command is immune to being killed when you disconnect your terminal or hang up a modem (its original purpose). The syntax for the nohup command is as follows:


nohup  command-string  [input-file]  output-file  &

Using the cron Daemon

If you run a command with the nohup command, the command executes immediately. If you want to run the command at a later time or on a “time-available” basis, you must invoke the services of the cron daemon.

The cron daemon is a command run in the background by Linux—or, more specifically, by init, the master program. cron provides scheduling services to all Linux processes. You can ask cron to run a program at a specific time, periodically, at a particular time every day, or whenever the load on cron permits.


See “Scheduling Commands with cron and crontab,” p. 388


Previous Table of Contents Next