## Command Separators

A single shell input line can request execution of more than one program. These programs may be executed sequentially or concurrently. Sequential execution means that one program must complete its function and terminate before the next program is allowed to begin execution. Concurrent execution means that several programs are allowed to begin execution and run simultaneously.

### Sequential Execution

Programs are executed sequentially when each is entered on a separate line. More than one program can be specified on a single shell command line by separating each `program name` `parameters` from the next one with a “;” character. For example:

    OS9: copy myfile /d1/newfile ; dir >/p

This command line will first execute the copy command and then the dir command.

If an error is returned by any program, subsequent commands on the same line are not executed (regardless of the state of the “x” option), otherwise, “;” and “return” are identical separators.

Here are some more examples:

    OS9: copy oldfile newfile; del oldfile; list newfile

    OS9: dir >/d1/myfile ; list temp >/p; del temp

All programs executed sequentially are in fact separate, child processes of the shell. After initiating execution of a program to be executed sequentially, the shell enters the “wait” state until execution of the called program terminates.

### Concurrent Execution

The second kind of separator is the “&” which implies concurrent execution, meaning that the program is run (as a separate, child process), but the shell does not wait for it to complete before processing the next command.

The concurrent execution separator is therefore the means by which multiprogramming (running two or more programs simultaneously) is accomplished. The number of programs that can run at the same time is not fixed: it depends upon the amount of free memory in the system versus the memory requirements of the specific programs. Here is an example:

    OS9: dir >/p&
    &007

    OS9:

This command line will cause shell to start the dir command executing, print the process ID number (&007), and then immediately display the “OS9:” prompt and wait for another command to be entered. Meanwhile the dir command will be busy sending a directory listing to the printer. You can display a “status summary” of all processes you have created by using the procs command. Below is another example:

    OS9: dir >/p& list file1& copy file1 file2 ; del temp

Because they were followed by “&” separators, the dir, list, and copy programs will run concurrently, but the del program will not run until the copy program has terminated because sequential execution (“;”) was specified.

### Pipes and Filters

The third kind of separator is the “!” character which is used to construct “pipelines”. Pipelines consist of two or more concurrent programs whose standard input and/or output paths connect to each other using “pipes”.

Pipes are the primary means-by which data is transferred from process to process (interprocess communications). Pipes are first-in, first-out buffers that behave like mass-storage files.

I/O transfers using pipes are automatically buffered and synchronized. A single pipe may have several “readers” and several “writers”. Multiple writers send, and multiple readers accept, data to/from the pipe on a first-come, first-serve basis. An end-of-file will occur if an attempt is made to read from a pipe but there are no writers available to send data. Conversely, a write error will occur if an attempt is made to write to a pipe having no readers.

Pipelines are created by the shell when an input line having one or more “!” separators is processed. For each “!”, the standard output of the program named to the left of the “!” is redirected via a pipe to the standard input of the program named to the right of the “!”. Individual pipes are created for each “!” present. For example:

    OS9: update <master_file ! sort ! write_report >/p

In the example above, the program update has its input redirected from a path called `master_file`. Its standard output becomes the standard input for the program sort. Its output, in turn, becomes the standard input for the program write_report, which has its standard output redirected to the printer.

All programs in a pipeline are executed concurrently. The pipes automatically synchronize the programs so the output of one never “gets ahead” of the input request of the next program in the pipeline. This implies that data cannot flow through a pipeline any faster than the slowest program can process it. Some of the most useful applications of pipelines are jobs like character set conversion, print file formatting, data compression/decompression, etc. Programs which are designed to process data as components of a pipeline are often called “filters”. The tee command, which uses pipes to allow data to be simultaneously “broadcast” from a single input path to several output paths, is a useful filter.