Multiple Commands, Sub-commands and Background Commands

The shell allows you to run several commands on one command line. Each command must be separated with a semicolon. For example

$ cd $HOME; ls -l | more; dostuff

Often after changing the permissions on a file, you want to do a directory listing to see if you did things right.

$ chmod u+x script; ls -l script

You can arrange things so that a second command executes only if the first command returns a successful status code (zero). For example

$ prog1 && prog2

Here prog1 is executed first. If prog1 returns a status code of zero, prog2 is executed. On the other hand if prog1 fails, prog2 is not attempted. The overall command stops after the first failed program.

You can also do

$ prog1 || prog2

Here prog2 is executed only if prog1 fails. That is the command stops after the first successful program.

You can force commands to be executed in a subshell by enclosing them in parenthesis. Since a subshell has it's own working directory and shell variables, this can be useful in some situations. Compare

$ pwd
/home/pchapin
$ echo $NAME
Peter
$ cd ..; NAME=PHOO
$ pwd
/home
$ echo $NAME
PHOO
$

with

$ pwd
/home/pchapin
$ echo NAME
Peter
$ (cd ..; NAME=PHOO)
$ pwd
/home/pchapin
$ echo NAME
Peter
$

The output of a command executed in a subshell can be redirected as a group. Compare

$ prog1; prog2 > afile.txt
$ (prog1; prog2) > afile.txt

In the first case only the output of prog2 is redirected. In the second case the output of both commands are redirected.

Since Unix is multitasking, it can run programs in the background while you enter additional commands. This is done by putting a '&' character at the end of the command line. For example:

$ prog args &
$

Notice that in the example above, the standard output of the background command is still the terminal. Thus any output produced by prog will be written directly on the terminal right over whatever else you are doing. Since this is usually not desireable, you should normally redirect the output of a background command.

$ prog1 | prog2 > afile.txt 2> errors.txt &
$

As you can see, pipelines can be run in the background. Also note that the standard error file has also been redirected with the '2>' operator. Thus error messages are prevented from interrupting your foreground process also.

It is possible to run multiple commands in the background by specifying a subshell or to run loops in the background (in which case a subshell is implicitly specified). For example

$ (prog1; prog2) &
$ for FILE in *
>   process $FILE
> done &
$