Classic Shell Scripting - Arnold Robbins [95]
Subshells and Code Blocks
Two other constructs are occasionally useful: subshells and code blocks.
A subshell is a group of commands enclosed in parentheses. The commands are run in a separate process.[5] This is particularly useful if you need a small group of commands to run in a different directory, without changing the directory of the main script. For example, the following pipeline, for copying a directory tree from one place to another, was in the original V7 Unix tar(1) manpage:
tar -cf - . | (cd /newdir; tar -xpf -)
The lefthand tar command creates a tar archive of the current directory, sending it to standard output. This archive goes down the pipe to the commands in the subshell on the right. The leading cd command first changes to the new directory where the archive is to be extracted. Then the righthand tar command extracts the files from the archive. Note that the shell (or script) running this pipeline has not changed its directory.
A code block is conceptually similar to a subshell, but it does not create a new process. Commands in a code block are enclosed in braces, and do affect the main script's state (such as its current directory). For historical reasons, the braces are treated as shell keywords: this means that they're recognized only as the first symbol in a command. Practically speaking, this means that you must place the closing brace after a newline or after a semicolon. For example:
cd /some/directory || { Start code block
echo could not change to /some/directory! >&2 What went wrong
echo you lose! >&2 Snide remark
exit 1 Terminate whole script
} End of code block
I/O redirection may be applied to subshells (as shown in the two-tar example) and code blocks. In that case, all the commands read their input or send their output from the redirected source. Table 7-8 summarizes the differences between subshells and code blocks.
Table 7-8. Subshell and code block summary
Construct
Delimiters
Recognized where
Separate process
Subshell
( )
Anywhere on the line
Yes
Code block
{ }
After newline, semicolon, or keyword
No
When to use a subshell versus when to use a code block is mostly a matter of taste and judgment. The primary difference is that a code block shares state with the main script. Thus, a cd command affects the main script, as do variable assignments. In particular, an exit in a code block terminates the entire script. Thus, you should use a subshell when you want the enclosed commands to run without affecting the main script. Otherwise, use a code block.
* * *
[5] The POSIX standard terms it a "subshell environment." This means that the commands need not actually run in a separate process; rather, they simply are forbidden to change the environment (variables, current directory, and so on) of the main script. ksh93 will avoid starting an actual process for subshell commands if it can. Most other shells do create a separate process.
Built-in Commands
The shell has a number of commands that are built-in. This means that the shell itself executes the command, instead of running an external program in a separate process. Furthermore, POSIX distinguishes between "special" built-ins and "regular" built-ins. The built-in commands are listed in Table 7-9. Special built-ins are marked with a †. Most of the regular built-ins listed here have to be built-in for the shell to function correctly (e.g., read). Others are typically built into the shell only for efficiency (e.g., true and false). The standard allows other commands to be built-in for efficiency as well, but all regular built-ins must be accessible as separate programs that can be executed directly by other binary programs. test is a primary example of a command that often is built into the shell for efficiency reasons.
Table 7-9. POSIX shell built-in commands
Command
Summary
: (colon)[6]
Do nothing (just do expansions of arguments).
. (dot)