A number-sign (#) and any following characters up to (but not including) the next newline are ignored, except in quotation marks.
If the name ends in .dis, sh looks for a Dis module of that name; otherwise it tries first to find a Dis module of that name with .dis appended and failing that, it looks for an executable file of the same name, which should be a readable, executable script file. If the name does not start with a slash (/) or dot-slash (./), then the name is first looked for relative to /dis, and then relative to the current directory. A Dis module will be executed only if it implements the Command interface (see sh(1)); a script file will be executed only if it starts with the characters ``#!'' followed by the name of a file executable under the rules above. In this case the command will be executed with any following arguments mentioned in the #! header, followed by the path of the script file, followed by any arguments originally given to the command.
For example, to execute the simple command ls, sh will look for one of the following things, in order, stopping the search when one is found:
The simplest kind of argument is the unquoted word: a sequence of one or more characters none of which is a blank, tab, newline, or any of the following:
# ; & | ^ $ ` ' { } ( ) < > " =An unquoted word that contains any of the characters * ? [ is a pattern for matching against file names. The character * matches any sequence of characters, ? matches any single character, and [class] matches any character in the class. If the first character of class is ^, the class is complemented. (As this character is special to the shell, it may only be included in a pattern if this character is quoted, as long as the leading [ is not quoted). The class may also contain pairs of characters separated by -, standing for all characters lexically between the two. The character / must appear explicitly in a pattern. A pattern is replaced by a list of arguments, one for each path name matched, except that a pattern matching no names is not replaced by the empty list, but rather stands for itself. Pattern matching is done after all other operations. Thus,
x=/tmp; echo $x^/*.bmatches /tmp/*.b, rather than matching /*.b and then prefixing /tmp.
A quoted word is a sequence of characters surrounded by single quotes ('). A single quote is represented in a quoted word by a pair of quotes ('').
Each of the following is an argument.
echo hi there everybody ((echo) (hi there) everybody) echo (hi there everybody )Newlines within parentheses count as simple white space; they do not terminate the command. This can be useful to give some more freedom of layout to commands that take several commands as arguments, for instance several of the commands defined in sh-std(1).
cmp <{old} <{new}
is equivalent to
A list of names can also be used in place of name, which causes each element of value in turn to be assigned the respective variable name in the list. The last variable in the list is assigned any elements that are left over. If there are more variable names than elements in value, the remaining elements are assigned the null list. For instance, after the assignment:
(a b c) = one two three four five$a is one, $b is two, and $c contains the remaining three elements (three four five).
Redirections may be applied to a file-descriptor other than standard input or output by qualifying the redirection operator with a number in square brackets. For example, the diagnostic output (file descriptor 2) may be redirected by writing limbo junk.b >[2] junk.
A file descriptor may be redirected to an already open descriptor by writing >[fd0=fd1] or <[fd0=fd1]. Fd1 is a previously opened file descriptor and fd0 becomes a new copy (in the sense of sys-dup(2)) of it.
Redirections are executed from left to right. Therefore, limbo junk.b >/dev/null >[2=1] and limbo junk.b >[2=1] >/dev/null have different effects: the first puts standard output in /dev/null and then puts diagnostic output in the same place, where the second directs diagnostic output to the terminal and sends standard output to /dev/null.
A sequence of commands separated by &, ;, or newline may be grouped by surrounding them with braces ({}), elsewhere referred to as a braced block. A braced block may be used anywhere that a simple word is expected. If a simple command is found with a braced block as its first word, the variable $* is set to any following arguments, $0 is set to the block itself, and the commands are executed in sequence. If a braced block is passed as an argument, no execution takes place: the block is converted to a functionally equivalent string, suitable for later re-interpretation by the shell. The null command ({}) has no effect and always gives a nil status. For instance the following commands all produce the same result:
echo hello world {echo hello world} '{echo hello world}' {echo $*} hello world sh -c {echo hello world} {$*} {echo hello world} {$*} {{$*} {echo hello world}} "{echo {echo hello world}} '{echo hello' ^ ' world}' x := {echo hello world}; $xIt is important to note that the value of $* is lost every time a braced block is entered, so for instance, the following command prints an empty string:
{{echo $*}} hello world
Given sh's ability to pass compound commands (braced blocks) as arguments to other commands, most control-flow functionality that is traditionally hard-wired into a shell is in sh implemented by loadable modules. See sh-std(1), sh-expr(1), and sh-tk(1) for more details.
There are two classes of built-in commands; the first class, known simply as ``builtins'', are used in the same way as normal commands, the only difference being that builtins can raise exceptions, while external commands cannot, as they are run in a separate process. The second class, known as ``builtin substitutions'' can only be used as the first word of the command in the ${} operator. The two classes exist in different name-spaces: a builtin may do something quite different from a builtin substitution of the same name.
In general, normal builtins perform some action or test some condition; the return status of a normal builtin usually indicates error status or conditional success. The rôle of a substitution builtin is to yield a value, (possibly a list) which is substituted directly into place as part of the argument list of a command.
When sh starts executing it reads variable definitions from its environment.
Internally, the shell holds a context, which holds a stack of environment variables, the current execution flags and the list of built-in modules. A copy is made whereever parallel access to the context might occur. This happens for processes executing in a pipeline, processes run asynchronously with &, and in any builtin command that runs a shell command asynchronously.
While it is possible to use the shell as a general purpose programming language, it is a very slow one! Intensive tasks are best done in Limbo, which is a much safer language to boot.
SH(1 ) | Rev: Wed Oct 03 13:15:21 GMT 2007 |