1840 lines
78 KiB
HTML
1840 lines
78 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<link type="text/css" rel="stylesheet" href="style.css"><!-- Generated by The Open Group's rhtm tool v1.2.1 -->
|
|
<!-- Copyright (c) 2001 The Open Group, All Rights Reserved -->
|
|
<title>Rationale</title>
|
|
</head>
|
|
<body>
|
|
|
|
<basefont size="3">
|
|
|
|
<center><font size="2">The Open Group Base Specifications Issue 6<br>
|
|
IEEE Std 1003.1-2001<br>
|
|
Copyright © 2001 The IEEE and The Open Group</font></center>
|
|
|
|
<hr size="2" noshade>
|
|
<h3><a name="tag_02_02"></a>Shell Command Language</h3>
|
|
|
|
<h4><a name="tag_02_02_01"></a>Shell Introduction</h4>
|
|
|
|
<p>The System V shell was selected as the starting point for the Shell and Utilities volume of IEEE Std 1003.1-2001.
|
|
The BSD C shell was excluded from consideration for the following reasons:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>Most historically portable shell scripts assume the Version 7 Bourne shell, from which the System V shell is derived.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>The majority of tutorial materials on shell programming assume the System V shell.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>The construct <tt>"#!"</tt> is reserved for implementations wishing to provide that extension. If it were not reserved, the
|
|
Shell and Utilities volume of IEEE Std 1003.1-2001 would disallow it by forcing it to be a comment. As it stands, a
|
|
strictly conforming application must not use <tt>"#!"</tt> as the first two characters of the file.</p>
|
|
|
|
<h4><a name="tag_02_02_02"></a>Quoting</h4>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_02_01"></a>Escape Character (Backslash)</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_02_02"></a>Single-Quotes</h5>
|
|
|
|
<p>A backslash cannot be used to escape a single-quote in a single-quoted string. An embedded quote can be created by writing, for
|
|
example: <tt>"'a'\''b'"</tt> , which yields <tt>"a'b"</tt> . (See the Shell and Utilities volume of IEEE Std 1003.1-2001,
|
|
<a href="../utilities/xcu_chap02.html#tag_02_06_05">Section 2.6.5, Field Splitting</a> for a better understanding of how portions
|
|
of words are either split into fields or remain concatenated.) A single token can be made up of concatenated partial strings
|
|
containing all three kinds of quoting or escaping, thus permitting any combination of characters.</p>
|
|
|
|
<h5><a name="tag_02_02_02_03"></a>Double-Quotes</h5>
|
|
|
|
<p>The escaped <newline> used for line continuation is removed entirely from the input and is not replaced by any white
|
|
space. Therefore, it cannot serve as a token separator.</p>
|
|
|
|
<p>In double-quoting, if a backslash is immediately followed by a character that would be interpreted as having a special meaning,
|
|
the backslash is deleted and the subsequent character is taken literally. If a backslash does not precede a character that would
|
|
have a special meaning, it is left in place unmodified and the character immediately following it is also left unmodified. Thus,
|
|
for example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>"\$" -> $
|
|
<br>
|
|
"\a" -> \a
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>It would be desirable to include the statement "The characters from an enclosed <tt>"${"</tt> to the matching <tt>'}'</tt>
|
|
shall not be affected by the double quotes", similar to the one for <tt>"$()"</tt> . However, historical practice in the
|
|
System V shell prevents this.</p>
|
|
|
|
<p>The requirement that double-quotes be matched inside <tt>"${...}"</tt> within double-quotes and the rule for finding the
|
|
matching <tt>'}'</tt> in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a href=
|
|
"../utilities/xcu_chap02.html#tag_02_06_02">Section 2.6.2, Parameter Expansion</a> eliminate several subtle inconsistencies in
|
|
expansion for historical shells in rare cases; for example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>"${foo-bar"}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>yields <b>bar</b> when <b>foo</b> is not defined, and is an invalid substitution when <b>foo</b> is defined, in many historical
|
|
shells. The differences in processing the <tt>"${...}"</tt> form have led to inconsistencies between historical systems. A
|
|
consequence of this rule is that single-quotes cannot be used to quote the <tt>'}'</tt> within <tt>"${...}"</tt> ; for example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>unset bar
|
|
foo="${bar-'}'}"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>is invalid because the <tt>"${...}"</tt> substitution contains an unpaired unescaped single-quote. The backslash can be used to
|
|
escape the <tt>'}'</tt> in this example to achieve the desired result:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>unset bar
|
|
foo="${bar-\}}"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The differences in processing the <tt>"${...}"</tt> form have led to inconsistencies between the historical System V shell,
|
|
BSD, and KornShells, and the text in the Shell and Utilities volume of IEEE Std 1003.1-2001 is an attempt to converge
|
|
them without breaking too many applications. The only alternative to this compromise between shells would be to make the behavior
|
|
unspecified whenever the literal characters <tt>'"</tt> , <tt>'{'</tt> , <tt>'}'</tt> , and <tt>''</tt> appear within
|
|
<tt>"${...}"</tt> . To write a portable script that uses these values, a user would have to assign variables; for example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>squote=\' dquote=\" lbrace='{' rbrace='}'
|
|
${foo-$squote$rbrace$squote}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>rather than:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>${foo-"'}'"}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Some implementations have allowed the end of the word to terminate the backquoted command substitution, such as in:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>"`echo hello"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>This usage is undefined; the matching backquote is required by the Shell and Utilities volume of IEEE Std 1003.1-2001.
|
|
The other undefined usage can be illustrated by the example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>sh -c '` echo "foo`'
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The description of the recursive actions involving command substitution can be illustrated with an example. Upon recognizing the
|
|
introduction of command substitution, the shell parses input (in a new context), gathering the source for the command substitution
|
|
until an unbalanced <tt>')'</tt> or <tt>'`'</tt> is located. For example, in the following:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo "$(date; echo "
|
|
one" )"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>the double-quote following the <a href="../utilities/echo.html"><i>echo</i></a> does not terminate the first double-quote; it is
|
|
part of the command substitution script. Similarly, in:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo "$(echo *)"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>the asterisk is not quoted since it is inside command substitution; however:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo "$(echo "*")"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>is quoted (and represents the asterisk character itself).</p>
|
|
|
|
<h4><a name="tag_02_02_03"></a>Token Recognition</h4>
|
|
|
|
<p>The <tt>"(("</tt> and <tt>"))"</tt> symbols are control operators in the KornShell, used for an alternative syntax of an
|
|
arithmetic expression command. A conforming application cannot use <tt>"(("</tt> as a single token (with the exception of the
|
|
<tt>"$(("</tt> form for shell arithmetic).</p>
|
|
|
|
<p>On some implementations, the symbol <tt>"(("</tt> is a control operator; its use produces unspecified results. Applications that
|
|
wish to have nested subshells, such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>((echo Hello);(echo World))
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>must separate the <tt>"(("</tt> characters into two tokens by including white space between them. Some systems may treat these
|
|
as invalid arithmetic expressions instead of subshells.</p>
|
|
|
|
<p>Certain combinations of characters are invalid in portable scripts, as shown in the grammar. Implementations may use these
|
|
combinations (such as <tt>"|&"</tt> ) as valid control operators. Portable scripts cannot rely on receiving errors in all cases
|
|
where this volume of IEEE Std 1003.1-2001 indicates that a syntax is invalid.</p>
|
|
|
|
<p>The (3) rule about combining characters to form operators is not meant to preclude systems from extending the shell language
|
|
when characters are combined in otherwise invalid ways. Conforming applications cannot use invalid combinations, and test suites
|
|
should not penalize systems that take advantage of this fact. For example, the unquoted combination <tt>"|&"</tt> is not valid
|
|
in a POSIX script, but has a specific KornShell meaning.</p>
|
|
|
|
<p>The (10) rule about <tt>'#'</tt> as the current character is the first in the sequence in which a new token is being assembled.
|
|
The <tt>'#'</tt> starts a comment only when it is at the beginning of a token. This rule is also written to indicate that the
|
|
search for the end-of-comment does not consider escaped <newline> specially, so that a comment cannot be continued to the
|
|
next line.</p>
|
|
|
|
<h5><a name="tag_02_02_03_01"></a>Alias Substitution</h5>
|
|
|
|
<p>The alias capability was added in the User Portability Utilities option because it is widely used in historical implementations
|
|
by interactive users.</p>
|
|
|
|
<p>The definition of "alias name" precludes an alias name containing a slash character. Since the text applies to the command
|
|
words of simple commands, reserved words (in their proper places) cannot be confused with aliases.</p>
|
|
|
|
<p>The placement of alias substitution in token recognition makes it clear that it precedes all of the word expansion steps.</p>
|
|
|
|
<p>An example concerning trailing <blank>s and reserved words follows. If the user types:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>alias foo="/bin/ls "
|
|
</tt><b>$</b> <tt>alias while="/"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The effect of executing:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>while true
|
|
</tt><b>></b> <tt>do
|
|
</tt><b>></b> <tt>echo "Hello, World"
|
|
</tt><b>></b> <tt>done
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>is a never-ending sequence of <tt>"Hello, World"</tt> strings to the screen. However, if the user types:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>foo while
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>the result is an <a href="../utilities/ls.html"><i>ls</i></a> listing of <b>/</b>. Since the alias substitution for <b>foo</b>
|
|
ends in a <space>, the next word is checked for alias substitution. The next word, <b>while</b>, has also been aliased, so it
|
|
is substituted as well. Since it is not in the proper position as a command word, it is not recognized as a reserved word.</p>
|
|
|
|
<p>If the user types:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>foo; while
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p><b>while</b> retains its normal reserved-word properties.</p>
|
|
|
|
<h4><a name="tag_02_02_04"></a>Reserved Words</h4>
|
|
|
|
<p>All reserved words are recognized syntactically as such in the contexts described. However, note that <b>in</b> is the only
|
|
meaningful reserved word after a <b>case</b> or <b>for</b>; similarly, <b>in</b> is not meaningful as the first word of a simple
|
|
command.</p>
|
|
|
|
<p>Reserved words are recognized only when they are delimited (that is, meet the definition of the Base Definitions volume of
|
|
IEEE Std 1003.1-2001, <a href="../basedefs/xbd_chap03.html#tag_03_435">Section 3.435, Word</a>), whereas operators are
|
|
themselves delimiters. For instance, <tt>'('</tt> and <tt>')'</tt> are control operators, so that no <space> is needed in
|
|
(<i>list</i>). However, <tt>'{'</tt> and <tt>'}'</tt> are reserved words in { <i>list</i>;}, so that in this case the leading
|
|
<space> and semicolon are required.</p>
|
|
|
|
<p>The list of unspecified reserved words is from the KornShell, so conforming applications cannot use them in places a reserved
|
|
word would be recognized. This list contained <b>time</b> in early proposals, but it was removed when the <a href=
|
|
"../utilities/time.html"><i>time</i></a> utility was selected for the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001.</p>
|
|
|
|
<p>There was a strong argument for promoting braces to operators (instead of reserved words), so they would be syntactically
|
|
equivalent to subshell operators. Concerns about compatibility outweighed the advantages of this approach. Nevertheless, conforming
|
|
applications should consider quoting <tt>'{'</tt> and <tt>'}'</tt> when they represent themselves.</p>
|
|
|
|
<p>The restriction on ending a name with a colon is to allow future implementations that support named labels for flow control; see
|
|
the RATIONALE for the <a href="../utilities/break.html"><i>break</i></a> built-in utility.</p>
|
|
|
|
<p>It is possible that a future version of the Shell and Utilities volume of IEEE Std 1003.1-2001 may require that
|
|
<tt>'{'</tt> and <tt>'}'</tt> be treated individually as control operators, although the token <tt>"{}"</tt> will probably be a
|
|
special-case exemption from this because of the often-used <a href="../utilities/find.html"><i>find</i></a>{} construct.</p>
|
|
|
|
<h4><a name="tag_02_02_05"></a>Parameters and Variables</h4>
|
|
|
|
<h5><a name="tag_02_02_05_01"></a>Positional Parameters</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_05_02"></a>Special Parameters</h5>
|
|
|
|
<p>Most historical implementations implement subshells by forking; thus, the special parameter <tt>'$'</tt> does not necessarily
|
|
represent the process ID of the shell process executing the commands since the subshell execution environment preserves the value
|
|
of <tt>'$'</tt> .</p>
|
|
|
|
<p>If a subshell were to execute a background command, the value of <tt>"$!"</tt> for the parent would not change. For example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>(
|
|
date &
|
|
echo $!
|
|
)
|
|
echo $!
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>would echo two different values for <tt>"$!"</tt> .</p>
|
|
|
|
<p>The <tt>"$-"</tt> special parameter can be used to save and restore <a href="../utilities/set.html"><i>set</i></a>
|
|
options:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>Save=$(echo $- | sed 's/[ics]//g')
|
|
...
|
|
set +aCefnuvx
|
|
if [ -n "$Save" ]; then
|
|
set -$Save
|
|
fi
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The three options are removed using <a href="../utilities/sed.html"><i>sed</i></a> in the example because they may appear in the
|
|
value of <tt>"$-"</tt> (from the <a href="../utilities/sh.html"><i>sh</i></a> command line), but are not valid options to <a href=
|
|
"../utilities/set.html"><i>set</i></a>.</p>
|
|
|
|
<p>The descriptions of parameters <tt>'*'</tt> and <tt>'@'</tt> assume the reader is familiar with the field splitting discussion
|
|
in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a href="../utilities/xcu_chap02.html#tag_02_06_05">Section
|
|
2.6.5, Field Splitting</a> and understands that portions of the word remain concatenated unless there is some reason to split them
|
|
into separate fields.</p>
|
|
|
|
<p>Some examples of the <tt>'*'</tt> and <tt>'@'</tt> properties, including the concatenation aspects:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>set "abc" "def ghi" "jkl"
|
|
<br>
|
|
echo $* => "abc" "def" "ghi" "jkl"
|
|
echo "$*" => "abc def ghi jkl"
|
|
echo $@ => "abc" "def" "ghi" "jkl"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>but:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo "$@" => "abc" "def ghi" "jkl"
|
|
echo "xx$@yy" => "xxabc" "def ghi" "jklyy"
|
|
echo "$@$@" => "abc" "def ghi" "jklabc" "def ghi" "jkl"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>In the preceding examples, the double-quote characters that appear after the <tt>"=>"</tt> do not appear in the output and
|
|
are used only to illustrate word boundaries.</p>
|
|
|
|
<p>The following example illustrates the effect of setting <i>IFS</i> to a null string:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>IFS=''
|
|
</tt><b>$</b> <tt>set foo bar bam
|
|
</tt><b>$</b> <tt>echo "$@"
|
|
</tt><b>foo bar bam</b><tt>
|
|
</tt><b>$</b> <tt>echo "$*"
|
|
</tt><b>foobarbam</b><tt>
|
|
</tt><b>$</b> <tt>unset IFS
|
|
</tt><b>$</b> <tt>echo "$*"
|
|
</tt><b>foo bar bam</b><tt>
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h5><a name="tag_02_02_05_03"></a>Shell Variables</h5>
|
|
|
|
<p>See the discussion of <i>IFS</i> in <a href="#tag_02_02_06_05">Field Splitting</a> and the RATIONALE for the <a href=
|
|
"../utilities/sh.html"><i>sh</i></a> utility.</p>
|
|
|
|
<p>The prohibition on <i>LC_CTYPE</i> changes affecting lexical processing protects the shell implementor (and the shell
|
|
programmer) from the ill effects of changing the definition of <blank> or the set of alphabetic characters in the current
|
|
environment. It would probably not be feasible to write a compiled version of a shell script without this rule. The rule applies
|
|
only to the current invocation of the shell and its subshells-invoking a shell script or performing <a href=
|
|
"../utilities/exec.html"><i>exec</i></a> <a href="../utilities/sh.html"><i>sh</i></a> would subject the new shell to the
|
|
changes in <i>LC_CTYPE .</i></p>
|
|
|
|
<p>Other common environment variables used by historical shells are not specified by the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001, but they should be reserved for the historical uses.</p>
|
|
|
|
<p>Tilde expansion for components of <i>PATH</i> in an assignment such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>PATH=˜hlj/bin:˜dwc/bin:$PATH
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>is a feature of some historical shells and is allowed by the wording of the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001, <a href="../utilities/xcu_chap02.html#tag_02_06_01">Section 2.6.1, Tilde Expansion</a>. Note that
|
|
the tildes are expanded during the assignment to <i>PATH ,</i> not when <i>PATH</i> is accessed during command search.</p>
|
|
|
|
<p>The following entries represent additional information about variables included in the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001, or rationale for common variables in use by shells that have been excluded:</p>
|
|
|
|
<dl compact>
|
|
<dt><tt>_</tt></dt>
|
|
|
|
<dd>(Underscore.) While underscore is historical practice, its overloaded usage in the KornShell is confusing, and it has been
|
|
omitted from the Shell and Utilities volume of IEEE Std 1003.1-2001.</dd>
|
|
|
|
<dt><i>ENV</i></dt>
|
|
|
|
<dd>This variable can be used to set aliases and other items local to the invocation of a shell. The file referred to by <i>ENV</i>
|
|
differs from <b>$HOME/.profile</b> in that <b>.profile</b> is typically executed at session start-up, whereas the <i>ENV</i> file
|
|
is executed at the beginning of each shell invocation. The <i>ENV</i> value is interpreted in a manner similar to a dot script, in
|
|
that the commands are executed in the current environment and the file needs to be readable, but not executable. However, unlike
|
|
dot scripts, no <i>PATH</i> searching is performed. This is used as a guard against Trojan Horse security breaches.</dd>
|
|
|
|
<dt><i>ERRNO</i></dt>
|
|
|
|
<dd>This variable was omitted from the Shell and Utilities volume of IEEE Std 1003.1-2001 because the values of error
|
|
numbers are not defined in IEEE Std 1003.1-2001 in a portable manner.</dd>
|
|
|
|
<dt><i>FCEDIT</i></dt>
|
|
|
|
<dd>Since this variable affects only the <a href="../utilities/fc.html"><i>fc</i></a> utility, it has been omitted from this more
|
|
global place. The value of <i>FCEDIT</i> does not affect the command-line editing mode in the shell; see the description of <a
|
|
href="../utilities/set.html"><i>set</i></a> <b>-o</b> <i>vi</i> in the <a href=
|
|
"../utilities/set.html"><i>set</i></a> built-in utility.</dd>
|
|
|
|
<dt><i>PS1</i></dt>
|
|
|
|
<dd>This variable is used for interactive prompts. Historically, the "superuser" has had a prompt of <tt>'#'</tt> . Since
|
|
privileges are not required to be monolithic, it is difficult to define which privileges should cause the alternate prompt.
|
|
However, a sufficiently powerful user should be reminded of that power by having an alternate prompt.</dd>
|
|
|
|
<dt><i>PS3</i></dt>
|
|
|
|
<dd>This variable is used by the KornShell for the <i>select</i> command. Since the POSIX shell does not include <i>select</i>,
|
|
<i>PS3</i> was omitted.</dd>
|
|
|
|
<dt><i>PS4</i></dt>
|
|
|
|
<dd>This variable is used for shell debugging. For example, the following script:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>PS4='[${LINENO}]+ '
|
|
set -x
|
|
echo Hello
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>writes the following to standard error:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>[3]+ echo Hello
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
</dd>
|
|
|
|
<dt><i>RANDOM</i></dt>
|
|
|
|
<dd>This pseudo-random number generator was not seen as being useful to interactive users.</dd>
|
|
|
|
<dt><i>SECONDS</i></dt>
|
|
|
|
<dd>Although this variable is sometimes used with <i>PS1</i> to allow the display of the current time in the prompt of the user, it
|
|
is not one that would be manipulated frequently enough by an interactive user to include in the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001.</dd>
|
|
</dl>
|
|
|
|
<h4><a name="tag_02_02_06"></a>Word Expansions</h4>
|
|
|
|
<p>Step (2) refers to the "portions of fields generated by step (1)". For example, if the word being expanded were
|
|
<tt>"$x+$y"</tt> and <i>IFS =+,</i> the word would be split only if <tt>"$x"</tt> or <tt>"$y"</tt> contained <tt>'+'</tt> ; the
|
|
<tt>'+'</tt> in the original word was not generated by step (1).</p>
|
|
|
|
<p><i>IFS</i> is used for performing field splitting on the results of parameter and command substitution; it is not used for
|
|
splitting all fields. Previous versions of the shell used it for splitting all fields during field splitting, but this has severe
|
|
problems because the shell can no longer parse its own script. There are also important security implications caused by this
|
|
behavior. All useful applications of <i>IFS</i> use it for parsing input of the <a href="../utilities/read.html"><i>read</i></a>
|
|
utility and for splitting the results of parameter and command substitution.</p>
|
|
|
|
<p>The rule concerning expansion to a single field requires that if <b>foo</b>= <b>abc</b> and <b>bar</b>= <b>def</b>, that:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>"$foo""$bar"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<br>
|
|
<p>expands to the single field:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>abcdef
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The rule concerning empty fields can be illustrated by:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt> unset foo
|
|
</tt><b>$</b> <tt> set $foo bar " xyz "$foo" abc
|
|
</tt><b>$</b> <tt> for i
|
|
</tt><b>></b> <tt> do
|
|
</tt><b>></b> <tt> echo "-$i-"
|
|
</tt><b>></b> <tt> done
|
|
</tt><b>-bar-
|
|
--
|
|
-xyz-
|
|
--
|
|
-abc-</b>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Step (1) indicates that parameter expansion, command substitution, and arithmetic expansion are all processed simultaneously as
|
|
they are scanned. For example, the following is valid arithmetic:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>x=1
|
|
echo $(( $(echo 3)+$x ))
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>An early proposal stated that tilde expansion preceded the other steps, but this is not the case in known historical
|
|
implementations; if it were, and if a referenced home directory contained a <tt>'$'</tt> character, expansions would result within
|
|
the directory name.</p>
|
|
|
|
<h5><a name="tag_02_02_06_01"></a>Tilde Expansion</h5>
|
|
|
|
<p>Tilde expansion generally occurs only at the beginning of words, but an exception based on historical practice has been
|
|
included:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>PATH=/posix/bin:˜dgk/bin
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>This is eligible for tilde expansion because tilde follows a colon and none of the relevant characters is quoted. Consideration
|
|
was given to prohibiting this behavior because any of the following are reasonable substitutes:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>PATH=$(printf %s ˜karels/bin : ˜bostic/bin)
|
|
<br>
|
|
for Dir in ˜maart/bin ˜srb/bin ...
|
|
do
|
|
PATH=${PATH:+$PATH:}$Dir
|
|
done
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>In the first command, explicit colons are used for each directory. In all cases, the shell performs tilde expansion on each
|
|
directory because all are separate words to the shell.</p>
|
|
|
|
<p>Note that expressions in operands such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>make -k mumble LIBDIR=˜chet/lib
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>do not qualify as shell variable assignments, and tilde expansion is not performed (unless the command does so itself, which <a
|
|
href="../utilities/make.html"><i>make</i></a> does not).</p>
|
|
|
|
<p>Because of the requirement that the word is not quoted, the following are not equivalent; only the last causes tilde
|
|
expansion:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>\˜hlj/ ˜h\lj/ ˜"hlj"/ ˜hlj\/ ˜hlj/
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>In an early proposal, tilde expansion occurred following any unquoted equals sign or colon, but this was removed because of its
|
|
complexity and to avoid breaking commands such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>rcp hostname:˜marc/.profile .
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>A suggestion was made that the special sequence <tt>"$˜"</tt> should be allowed to force tilde expansion anywhere. Since
|
|
this is not historical practice, it has been left for future implementations to evaluate. (The description in the Shell and
|
|
Utilities volume of IEEE Std 1003.1-2001, <a href="../utilities/xcu_chap02.html#tag_02_02">Section 2.2, Quoting</a>
|
|
requires that a dollar sign be quoted to represent itself, so the <tt>"$˜"</tt> combination is already unspecified.)</p>
|
|
|
|
<p>The results of giving tilde with an unknown login name are undefined because the KornShell <tt>"˜+"</tt> and
|
|
<tt>"˜-"</tt> constructs make use of this condition, but in general it is an error to give an incorrect login name with tilde.
|
|
The results of having <i>HOME</i> unset are unspecified because some historical shells treat this as an error.</p>
|
|
|
|
<h5><a name="tag_02_02_06_02"></a>Parameter Expansion</h5>
|
|
|
|
<p>The rule for finding the closing <tt>'}'</tt> in <tt>"${...}"</tt> is the one used in the KornShell and is upwardly-compatible
|
|
with the Bourne shell, which does not determine the closing <tt>'}'</tt> until the word is expanded. The advantage of this is that
|
|
incomplete expansions, such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>${foo
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>can be determined during tokenization, rather than during expansion.</p>
|
|
|
|
<p>The string length and substring capabilities were included because of the demonstrated need for them, based on their usage in
|
|
other shells, such as C shell and KornShell.</p>
|
|
|
|
<p>Historical versions of the KornShell have not performed tilde expansion on the word part of parameter expansion; however, it is
|
|
more consistent to do so.</p>
|
|
|
|
<h5><a name="tag_02_02_06_03"></a>Command Substitution</h5>
|
|
|
|
<p>The <tt>"$()"</tt> form of command substitution solves a problem of inconsistent behavior when using backquotes. For
|
|
example:</p>
|
|
|
|
<center>
|
|
<table border="1" cellpadding="3" align="center">
|
|
<tr valign="top">
|
|
<th align="center">
|
|
<p class="tent"><b>Command</b></p>
|
|
</th>
|
|
<th align="center">
|
|
<p class="tent"><b>Output</b></p>
|
|
</th>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent">echo '\$x'</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">\$x</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent">echo `echo '\$x'`</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">$x</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent">echo $(echo '\$x')</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">\$x</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
|
|
<p>Additionally, the backquoted syntax has historical restrictions on the contents of the embedded command. While the newer
|
|
<tt>"$()"</tt> form can process any kind of valid embedded script, the backquoted form cannot handle some valid scripts that
|
|
include backquotes. For example, these otherwise valid embedded scripts do not work in the left column, but do work on the
|
|
right:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo ` echo $(
|
|
cat <<\eof cat <<\eof
|
|
a here-doc with ` a here-doc with )
|
|
eof eof
|
|
` )
|
|
<br>
|
|
echo ` echo $(
|
|
echo abc # a comment with ` echo abc # a comment with )
|
|
` )
|
|
<br>
|
|
echo ` echo $(
|
|
echo '`' echo ')'
|
|
` )
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Because of these inconsistent behaviors, the backquoted variety of command substitution is not recommended for new applications
|
|
that nest command substitutions or attempt to embed complex scripts.</p>
|
|
|
|
<p>The KornShell feature:</p>
|
|
|
|
<blockquote>If <i>command</i> is of the form < <i>word</i>, <i>word</i> is expanded to generate a pathname, and the value of the
|
|
command substitution is the contents of this file with any trailing <newline>s deleted.</blockquote>
|
|
|
|
<p>was omitted from the Shell and Utilities volume of IEEE Std 1003.1-2001 because $( <a href=
|
|
"../utilities/cat.html"><i>cat</i></a> <i>word</i>) is an appropriate substitute. However, to prevent breaking numerous scripts
|
|
relying on this feature, it is unspecified to have a script within <tt>"$()"</tt> that has only redirections.</p>
|
|
|
|
<p>The requirement to separate <tt>"$("</tt> and <tt>'('</tt> when a single subshell is command-substituted is to avoid any
|
|
ambiguities with arithmetic expansion.</p>
|
|
|
|
<h5><a name="tag_02_02_06_04"></a>Arithmetic Expansion</h5>
|
|
|
|
<p>The <tt>"(())"</tt> form of KornShell arithmetic in early proposals was omitted. The standard developers concluded that there
|
|
was a strong desire for some kind of arithmetic evaluator to replace <a href="../utilities/expr.html"><i>expr</i></a>, and that
|
|
relating it to <tt>'$'</tt> makes it work well with the standard shell language, and it provides access to arithmetic evaluation in
|
|
places where accessing a utility would be inconvenient.</p>
|
|
|
|
<p>The syntax and semantics for arithmetic were changed for the ISO/IEC 9945-2:1993 standard. The language is essentially a
|
|
pure arithmetic evaluator of constants and operators (excluding assignment) and represents a simple subset of the previous
|
|
arithmetic language (which was derived from the KornShell <tt>"(())"</tt> construct). The syntax was changed from that of a command
|
|
denoted by ((<i>expression</i>)) to an expansion denoted by $((<i>expression</i>)). The new form is a dollar expansion (
|
|
<tt>'$'</tt> ) that evaluates the expression and substitutes the resulting value. Objections to the previous style of arithmetic
|
|
included that it was too complicated, did not fit in well with the use of variables in the shell, and its syntax conflicted with
|
|
subshells. The justification for the new syntax is that the shell is traditionally a macro language, and if a new feature is to be
|
|
added, it should be accomplished by extending the capabilities presented by the current model of the shell, rather than by
|
|
inventing a new one outside the model; adding a new dollar expansion was perceived to be the most intuitive and least destructive
|
|
way to add such a new capability.</p>
|
|
|
|
<p>In early proposals, a form $[<i>expression</i>] was used. It was functionally equivalent to the <tt>"$(())"</tt> of the current
|
|
text, but objections were lodged that the 1988 KornShell had already implemented <tt>"$(())"</tt> and there was no compelling
|
|
reason to invent yet another syntax. Furthermore, the <tt>"$[]"</tt> syntax had a minor incompatibility involving the patterns in
|
|
<b>case</b> statements.</p>
|
|
|
|
<p>The portion of the ISO C standard arithmetic operations selected corresponds to the operations historically supported in
|
|
the KornShell.</p>
|
|
|
|
<p>It was concluded that the <a href="../utilities/test.html"><i>test</i></a> command ( <b>[</b>) was sufficient for the majority
|
|
of relational arithmetic tests, and that tests involving complicated relational expressions within the shell are rare, yet could
|
|
still be accommodated by testing the value of <tt>"$(())"</tt> itself. For example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt># a complicated relational expression
|
|
while [ $(( (($x + $y)/($a * $b)) < ($foo*$bar) )) -ne 0 ]
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>or better yet, the rare script that has many complex relational expressions could define a function like this:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>val() {
|
|
return $((!$1))
|
|
}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>and complicated tests would be less intimidating:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>while val $(( (($x + $y)/($a * $b)) < ($foo*$bar) ))
|
|
do
|
|
# some calculations
|
|
done
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>A suggestion that was not adopted was to modify <a href="../utilities/true.html"><i>true</i></a> and <a href=
|
|
"../utilities/false.html"><i>false</i></a> to take an optional argument, and <a href="../utilities/true.html"><i>true</i></a> would
|
|
exit true only if the argument was non-zero, and <a href="../utilities/false.html"><i>false</i></a> would exit false only if the
|
|
argument was non-zero:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>while true $(($x > 5 && $y <= 25))
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>There is a minor portability concern with the new syntax. The example <tt>"$((2+2))"</tt> could have been intended to mean a
|
|
command substitution of a utility named <tt>"2+2"</tt> in a subshell. The standard developers considered this to be obscure and
|
|
isolated to some KornShell scripts (because <tt>"$()"</tt> command substitution existed previously only in the KornShell). The text
|
|
on command substitution requires that the <tt>"$("</tt> and <tt>'('</tt> be separate tokens if this usage is needed.</p>
|
|
|
|
<p>An example such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo $((echo hi);(echo there))
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>should not be misinterpreted by the shell as arithmetic because attempts to balance the parentheses pairs would indicate that
|
|
they are subshells. However, as indicated by the Base Definitions volume of IEEE Std 1003.1-2001, <a href=
|
|
"../basedefs/xbd_chap03.html#tag_03_112">Section 3.112, Control Operator</a>, a conforming application must separate two adjacent
|
|
parentheses with white space to indicate nested subshells.</p>
|
|
|
|
<p>Although the ISO/IEC 9899:1999 standard now requires support for <b>long long</b> and allows extended integer types with
|
|
higher ranks, IEEE Std 1003.1-2001 only requires arithmetic expansions to support <b>signed long</b> integer arithmetic.
|
|
Implementations are encouraged to support signed integer values at least as large as the size of the largest file allowed on the
|
|
implementation.</p>
|
|
|
|
<p>Implementations are also allowed to perform floating-point evaluations as long as an application won't see different results for
|
|
expressions that would not overflow <b>signed long</b> integer expression evaluation. (This includes appropriate truncation of
|
|
results to integer values.)</p>
|
|
|
|
<p>Changes made in response to IEEE PASC Interpretation 1003.2 #208 removed the requirement that the integer constant suffixes
|
|
<tt>l</tt> and <tt>L</tt> had to be recognized. The ISO POSIX-2:1993 standard did not require the <tt>u</tt> , <tt>ul</tt> ,
|
|
<tt>uL</tt> , <tt>U</tt> , <tt>Ul</tt> , <tt>UL</tt> , <tt>lu</tt> , <tt>lU</tt> , <tt>Lu</tt> , and <tt>LU</tt> suffixes since
|
|
only signed integer arithmetic was required. Since all arithmetic expressions were treated as handling <b>signed long</b> integer
|
|
types anyway, the <tt>l</tt> and <tt>L</tt> suffixes were redundant. No known scripts used them and some historic shells did not
|
|
support them. When the ISO/IEC 9899:1999 standard was used as the basis for the description of arithmetic processing, the
|
|
<tt>ll</tt> and <tt>LL</tt> suffixes and combinations were also not required. Implementations are still free to accept any or all
|
|
of these suffixes, but are not required to do so.</p>
|
|
|
|
<p>There was also some confusion as to whether the shell was required to recognize character constants. Syntactically, character
|
|
constants were required to be recognized, but the requirements for the handling of backslash ( <tt>'\'</tt> ) and quote (
|
|
<tt>'"</tt> ) characters (needed to specify character constants) within an arithmetic expansion were ambiguous. Furthermore, no
|
|
known shells supported them. Changes made in response to IEEE PASC Interpretation 1003.2 #208 removed the requirement to support
|
|
them (if they were indeed required before). IEEE Std 1003.1-2001 clearly does not require support for character
|
|
constants.</p>
|
|
|
|
<h5><a name="tag_02_02_06_05"></a>Field Splitting</h5>
|
|
|
|
<p>The operation of field splitting using <i>IFS ,</i> as described in early proposals, was based on the way the KornShell splits
|
|
words, but it is incompatible with other common versions of the shell. However, each has merit, and so a decision was made to allow
|
|
both. If the <i>IFS</i> variable is unset or is <space> <tab> <newline>, the operation is equivalent to the way
|
|
the System V shell splits words. Using characters outside the <space> <tab> <newline> set yields the
|
|
KornShell behavior, where each of the non- <space> <tab> <newline>s is significant. This behavior, which affords
|
|
the most flexibility, was taken from the way the original <a href="../utilities/awk.html"><i>awk</i></a> handled field
|
|
splitting.</p>
|
|
|
|
<p>Rule (3) can be summarized as a pseudo-ERE:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>(</tt><i>s</i><tt>*</tt><i>ns</i><tt>*|</tt><i>s</i><tt>+)
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>where <i>s</i> is an <i>IFS</i> white space character and <i>n</i> is a character in the <i>IFS</i> that is not white space. Any
|
|
string matching that ERE delimits a field, except that the <i>s</i>+ form does not delimit fields at the beginning or the end of a
|
|
line. For example, if <i>IFS</i> is <space>/ <comma>/ <tab>, the string:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt><space><space>red<space><space>,<space>white<space>blue
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>yields the three colors as the delimited fields.</p>
|
|
|
|
<h5><a name="tag_02_02_06_06"></a>Pathname Expansion</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_06_07"></a>Quote Removal</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h4><a name="tag_02_02_07"></a>Redirection</h4>
|
|
|
|
<p>In the System Interfaces volume of IEEE Std 1003.1-2001, file descriptors are integers in the range 0-({OPEN_MAX}-1).
|
|
The file descriptors discussed in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a href=
|
|
"../utilities/xcu_chap02.html#tag_02_07">Section 2.7, Redirection</a> are that same set of small integers.</p>
|
|
|
|
<p>Having multi-digit file descriptor numbers for I/O redirection can cause some obscure compatibility problems. Specifically,
|
|
scripts that depend on an example command:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>echo 22>/dev/null
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>echoing <tt>"2"</tt> to standard error or <tt>"22"</tt> to standard output are no longer portable. However, the file descriptor
|
|
number must still be delimited from the preceding text. For example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>cat file2>foo
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>writes the contents of <b>file2</b>, not the contents of <b>file</b>.</p>
|
|
|
|
<p>The <tt>">|"</tt> format of output redirection was adopted from the KornShell. Along with the <i>noclobber</i> option, <a
|
|
href="../utilities/set.html"><i>set</i></a> <b>-C</b>, it provides a safety feature to prevent inadvertent overwriting
|
|
of existing files. (See the RATIONALE for the <a href="../utilities/pathchk.html"><i>pathchk</i></a> utility for why this step was
|
|
taken.) The restriction on regular files is historical practice.</p>
|
|
|
|
<p>The System V shell and the KornShell have differed historically on pathname expansion of <i>word</i>; the former never
|
|
performed it, the latter only when the result was a single field (file). As a compromise, it was decided that the KornShell
|
|
functionality was useful, but only as a shorthand device for interactive users. No reasonable shell script would be written with a
|
|
command such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>cat foo > a*
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Thus, shell scripts are prohibited from doing it, while interactive users can select the shell with which they are most
|
|
comfortable.</p>
|
|
|
|
<p>The construct <tt>"2>&1"</tt> is often used to redirect standard error to the same file as standard output. Since the
|
|
redirections take place beginning to end, the order of redirections is significant. For example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>ls > foo 2>&1
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>directs both standard output and standard error to file <b>foo</b>. However:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>ls 2>&1 > foo
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>only directs standard output to file <b>foo</b> because standard error was duplicated as standard output before standard output
|
|
was directed to file <b>foo</b>.</p>
|
|
|
|
<p>The <tt>"<>"</tt> operator could be useful in writing an application that worked with several terminals, and occasionally
|
|
wanted to start up a shell. That shell would in turn be unable to run applications that run from an ordinary controlling terminal
|
|
unless it could make use of <tt>"<>"</tt> redirection. The specific example is a historical version of the pager <a href=
|
|
"../utilities/more.html"><i>more</i></a>, which reads from standard error to get its commands, so standard input and standard
|
|
output are both available for their usual usage. There is no way of saying the following in the shell without <tt>"<>"</tt>
|
|
:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>cat food | more - >/dev/tty03 2<>/dev/tty03
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Another example of <tt>"<>"</tt> is one that opens <b>/dev/tty</b> on file descriptor 3 for reading and writing:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>exec 3<> /dev/tty
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>An example of creating a lock file for a critical code region:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>set -C
|
|
until 2> /dev/null > lockfile
|
|
do sleep 30
|
|
done
|
|
set +C
|
|
</tt><i>perform critical function</i><tt>rm lockfile
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Since <b>/dev/null</b> is not a regular file, no error is generated by redirecting to it in <i>noclobber</i> mode.</p>
|
|
|
|
<p>Tilde expansion is not performed on a here-document because the data is treated as if it were enclosed in double quotes.</p>
|
|
|
|
<h5><a name="tag_02_02_07_01"></a>Redirecting Input</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_07_02"></a>Redirecting Output</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_07_03"></a>Appending Redirected Output</h5>
|
|
|
|
<p>Note that when a file is opened (even with the O_APPEND flag set), the initial file offset for that file is set to the beginning
|
|
of the file. Some historic shells set the file offset to the current end-of-file when <b>append</b> mode shell redirection was
|
|
used, but this is not allowed by IEEE Std 1003.1-2001.</p>
|
|
|
|
<h5><a name="tag_02_02_07_04"></a>Here-Document</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_07_05"></a>Duplicating an Input File Descriptor</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_07_06"></a>Duplicating an Output File Descriptor</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_07_07"></a>Open File Descriptors for Reading and Writing</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h4><a name="tag_02_02_08"></a>Exit Status and Errors</h4>
|
|
|
|
<h5><a name="tag_02_02_08_01"></a>Consequences of Shell Errors</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_08_02"></a>Exit Status for Commands</h5>
|
|
|
|
<p>There is a historical difference in <a href="../utilities/sh.html"><i>sh</i></a> and <i>ksh</i> non-interactive error behavior.
|
|
When a command named in a script is not found, some implementations of <a href="../utilities/sh.html"><i>sh</i></a> exit
|
|
immediately, but <i>ksh</i> continues with the next command. Thus, the Shell and Utilities volume of IEEE Std 1003.1-2001
|
|
says that the shell "may" exit in this case. This puts a small burden on the programmer, who has to test for successful
|
|
completion following a command if it is important that the next command not be executed if the previous command was not found. If
|
|
it is important for the command to have been found, it was probably also important for it to complete successfully. The test for
|
|
successful completion would not need to change.</p>
|
|
|
|
<p>Historically, shells have returned an exit status of 128+ <i>n</i>, where <i>n</i> represents the signal number. Since signal
|
|
numbers are not standardized, there is no portable way to determine which signal caused the termination. Also, it is possible for a
|
|
command to exit with a status in the same range of numbers that the shell would use to report that the command was terminated by a
|
|
signal. Implementations are encouraged to choose exit values greater than 256 to indicate programs that terminate by a signal so
|
|
that the exit status cannot be confused with an exit status generated by a normal termination.</p>
|
|
|
|
<p>Historical shells make the distinction between "utility not found" and "utility found but cannot execute" in their error
|
|
messages. By specifying two seldomly used exit status values for these cases, 127 and 126 respectively, this gives an application
|
|
the opportunity to make use of this distinction without having to parse an error message that would probably change from locale to
|
|
locale. The <a href="../utilities/command.html"><i>command</i></a>, <a href="../utilities/env.html"><i>env</i></a>, <a href=
|
|
"../utilities/nohup.html"><i>nohup</i></a>, and <a href="../utilities/xargs.html"><i>xargs</i></a> utilities in the Shell and
|
|
Utilities volume of IEEE Std 1003.1-2001 have also been specified to use this convention.</p>
|
|
|
|
<p>When a command fails during word expansion or redirection, most historical implementations exit with a status of 1. However,
|
|
there was some sentiment that this value should probably be much higher so that an application could distinguish this case from the
|
|
more normal exit status values. Thus, the language "greater than zero" was selected to allow either method to be implemented.</p>
|
|
|
|
<h4><a name="tag_02_02_09"></a>Shell Commands</h4>
|
|
|
|
<p>A description of an "empty command" was removed from an early proposal because it is only relevant in the cases of <a href=
|
|
"../utilities/sh.html"><i>sh</i></a> <b>-c</b> <tt>""</tt> , <i>system</i>( <tt>""</tt> ), or an empty shell-script file (such as
|
|
the implementation of <a href="../utilities/true.html"><i>true</i></a> on some historical systems). Since it is no longer mentioned
|
|
in the Shell and Utilities volume of IEEE Std 1003.1-2001, it falls into the silently unspecified category of behavior
|
|
where implementations can continue to operate as they have historically, but conforming applications do not construct empty
|
|
commands. (However, note that <a href="../utilities/sh.html"><i>sh</i></a> does explicitly state an exit status for an empty string
|
|
or file.) In an interactive session or a script with other commands, extra <newline>s or semicolons, such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>$ false
|
|
$
|
|
$ echo $?
|
|
1
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>would not qualify as the empty command described here because they would be consumed by other parts of the grammar.</p>
|
|
|
|
<h5><a name="tag_02_02_09_01"></a>Simple Commands</h5>
|
|
|
|
<p>The enumerated list is used only when the command is actually going to be executed. For example, in:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>true || $foo *
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>no expansions are performed.</p>
|
|
|
|
<p>The following example illustrates both how a variable assignment without a command name affects the current execution
|
|
environment, and how an assignment with a command name only affects the execution environment of the command:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>x=red
|
|
</tt><b>$</b> <tt>echo $x
|
|
</tt><b>red
|
|
$</b> <tt>export x
|
|
</tt><b>$</b> <tt>sh -c 'echo $x'
|
|
</tt><b>red
|
|
$</b> <tt>x=blue sh -c 'echo $x'
|
|
</tt><b>blue
|
|
$</b> <tt>echo $x
|
|
</tt><b>red</b><tt>
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>This next example illustrates that redirections without a command name are still performed:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <tt>ls foo
|
|
</tt><b>ls: foo: no such file or directory
|
|
$</b> <tt>> foo
|
|
</tt><b>$</b> <tt>ls foo
|
|
</tt><b>foo</b><tt>
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>A command without a command name, but one that includes a command substitution, has an exit status of the last command
|
|
substitution that the shell performed. For example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>if x=$(</tt><i>command</i><tt>)
|
|
then ...
|
|
fi
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>An example of redirections without a command name being performed in a subshell shows that the here-document does not disrupt
|
|
the standard input of the <b>while</b> loop:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>IFS=:
|
|
while read a b
|
|
do echo $a
|
|
<<-eof
|
|
Hello
|
|
eof
|
|
done </etc/passwd
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Following are examples of commands without command names in AND-OR lists:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>> foo || {
|
|
echo "error: foo cannot be created" >&2
|
|
exit 1
|
|
}
|
|
<br>
|
|
# set saved if /vmunix.save exists
|
|
test -f /vmunix.save && saved=1
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>Command substitution and redirections without command names both occur in subshells, but they are not necessarily the same ones.
|
|
For example, in:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>exec 3> file
|
|
var=$(echo foo >&3) 3>&1
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>it is unspecified whether <b>foo</b> is echoed to the file or to standard output.</p>
|
|
|
|
<h5><a name="tag_02_02_09_02"></a>Command Search and Execution</h5>
|
|
|
|
<p>This description requires that the shell can execute shell scripts directly, even if the underlying system does not support the
|
|
common <tt>"#!"</tt> interpreter convention. That is, if file <b>foo</b> contains shell commands and is executable, the following
|
|
executes <b>foo</b>:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>./foo
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The command search shown here does not match all historical implementations. A more typical sequence has been:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>Any built-in (special or regular)</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Functions</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Path search for executable files</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>But there are problems with this sequence. Since the programmer has no idea in advance which utilities might have been built
|
|
into the shell, a function cannot be used to override portably a utility of the same name. (For example, a function named <a href=
|
|
"../utilities/cd.html"><i>cd</i></a> cannot be written for many historical systems.) Furthermore, the <i>PATH</i> variable is
|
|
partially ineffective in this case, and only a pathname with a slash can be used to ensure a specific executable file is
|
|
invoked.</p>
|
|
|
|
<p>After the <a href="../functions/execve.html"><i>execve</i>()</a> failure described, the shell normally executes the file as a
|
|
shell script. Some implementations, however, attempt to detect whether the file is actually a script and not an executable from
|
|
some other architecture. The method used by the KornShell is allowed by the text that indicates non-text files may be bypassed.</p>
|
|
|
|
<p>The sequence selected for the Shell and Utilities volume of IEEE Std 1003.1-2001 acknowledges that special built-ins
|
|
cannot be overridden, but gives the programmer full control over which versions of other utilities are executed. It provides a
|
|
means of suppressing function lookup (via the <a href="../utilities/command.html"><i>command</i></a> utility) for the user's own
|
|
functions and ensures that any regular built-ins or functions provided by the implementation are under the control of the path
|
|
search. The mechanisms for associating built-ins or functions with executable files in the path are not specified by the Shell and
|
|
Utilities volume of IEEE Std 1003.1-2001, but the wording requires that if either is implemented, the application is not
|
|
able to distinguish a function or built-in from an executable (other than in terms of performance, presumably). The implementation
|
|
ensures that all effects specified by the Shell and Utilities volume of IEEE Std 1003.1-2001 resulting from the
|
|
invocation of the regular built-in or function (interaction with the environment, variables, traps, and so on) are identical to
|
|
those resulting from the invocation of an executable file.</p>
|
|
|
|
<h5><a name="tag_02_02_09_03"></a>Examples</h5>
|
|
|
|
<p>Consider three versions of the <a href="../utilities/ls.html"><i>ls</i></a> utility:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>The application includes a shell function named <a href="../utilities/ls.html"><i>ls</i></a>.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>The user writes a utility named <a href="../utilities/ls.html"><i>ls</i></a> and puts it in <b>/fred/bin</b>.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>The example implementation provides <a href="../utilities/ls.html"><i>ls</i></a> as a regular shell built-in that is invoked
|
|
(either by the shell or directly by <i>exec</i>) when the path search reaches the directory <b>/posix/bin</b>.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>If <i>PATH =</i> <b>/posix/bin</b>, various invocations yield different versions of <a href=
|
|
"../utilities/ls.html"><i>ls</i></a>:</p>
|
|
|
|
<center>
|
|
<table border="1" cellpadding="3" align="center">
|
|
<tr valign="top">
|
|
<th align="center">
|
|
<p class="tent"><b>Invocation</b></p>
|
|
</th>
|
|
<th align="center">
|
|
<p class="tent"><b>Version of <i>ls</i></b></p>
|
|
</th>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent"><i>ls</i> (from within application script)</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">(1) function</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent"><i>command ls</i> (from within application script)</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">(3) built-in</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent"><i>ls</i> (from within makefile called by application)</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">(3) built-in</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent"><i>system</i>("<i>ls</i>")</p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">(3) built-in</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr valign="top">
|
|
<td align="left">
|
|
<p class="tent"><i>PATH</i>="<b>/fred/bin</b>:$<i>PATH</i>" <i>ls</i></p>
|
|
</td>
|
|
<td align="left">
|
|
<p class="tent">(2) user's version</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</center>
|
|
|
|
<h5><a name="tag_02_02_09_04"></a>Pipelines</h5>
|
|
|
|
<p>Because pipeline assignment of standard input or standard output or both takes place before redirection, it can be modified by
|
|
redirection. For example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<b>$</b> <i>command1</i> <tt>2>&1 |</tt> <i>command2</i>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>sends both the standard output and standard error of <i>command1</i> to the standard input of <i>command2</i>.</p>
|
|
|
|
<p>The reserved word <b>!</b> allows more flexible testing using AND and OR lists.</p>
|
|
|
|
<p>It was suggested that it would be better to return a non-zero value if any command in the pipeline terminates with non-zero
|
|
status (perhaps the bitwise-inclusive OR of all return values). However, the choice of the last-specified command semantics are
|
|
historical practice and would cause applications to break if changed. An example of historical behavior:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>$ sleep 5 | (exit 4)
|
|
$ echo $?
|
|
4
|
|
$ (exit 4) | sleep 5
|
|
$ echo $?
|
|
0
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h5><a name="tag_02_02_09_05"></a>Lists</h5>
|
|
|
|
<p>The equal precedence of <tt>"&&"</tt> and <tt>"||"</tt> is historical practice. The standard developers evaluated the
|
|
model used more frequently in high-level programming languages, such as C, to allow the shell logical operators to be used for
|
|
complex expressions in an unambiguous way, but they could not allow historical scripts to break in the subtle way unequal
|
|
precedence might cause. Some arguments were posed concerning the <tt>"{}"</tt> or <tt>"()"</tt> groupings that are required
|
|
historically. There are some disadvantages to these groupings:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>The <tt>"()"</tt> can be expensive, as they spawn other processes on some implementations. This performance concern is primarily
|
|
an implementation issue.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>The <tt>"{}"</tt> braces are not operators (they are reserved words) and require a trailing space after each <tt>'{'</tt> , and
|
|
a semicolon before each <tt>'}'</tt> . Most programmers (and certainly interactive users) have avoided braces as grouping
|
|
constructs because of the problematic syntax required. Braces were not changed to operators because that would generate
|
|
compatibility issues even greater than the precedence question; braces appear outside the context of a keyword in many shell
|
|
scripts.</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>IEEE PASC Interpretation 1003.2 #204 is applied, clarifying that the operators <tt>"&&"</tt> and <tt>"||"</tt> are
|
|
evaluated with left associativity.</p>
|
|
|
|
<h5><a name="tag_02_02_09_06"></a>Asynchronous Lists</h5>
|
|
|
|
<p>The grammar treats a construct such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>foo & bar & bam &
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>as one "asynchronous list", but since the status of each element is tracked by the shell, the term "element of an
|
|
asynchronous list" was introduced to identify just one of the <b>foo</b>, <b>bar</b>, or <b>bam</b> portions of the overall
|
|
list.</p>
|
|
|
|
<p>Unless the implementation has an internal limit, such as {CHILD_MAX}, on the retained process IDs, it would require unbounded
|
|
memory for the following example:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>while true
|
|
do foo & echo $!
|
|
done
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The treatment of the signals SIGINT and SIGQUIT with asynchronous lists is described in the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001, <a href="../utilities/xcu_chap02.html#tag_02_11">Section 2.11, Signals and Error Handling</a>.</p>
|
|
|
|
<p>Since the connection of the input to the equivalent of <b>/dev/null</b> is considered to occur before redirections, the
|
|
following script would produce no output:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>exec < /etc/passwd
|
|
cat <&0 &
|
|
wait
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h5><a name="tag_02_02_09_07"></a>Sequential Lists</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_09_08"></a>AND Lists</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_09_09"></a>OR Lists</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_09_10"></a>Compound Commands</h5>
|
|
|
|
<h5><a name="tag_02_02_09_11"></a>Grouping Commands</h5>
|
|
|
|
<p>The semicolon shown in { <i>compound-list</i>;} is an example of a control operator delimiting the <b>}</b> reserved word. Other
|
|
delimiters are possible, as shown in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a href=
|
|
"../utilities/xcu_chap02.html#tag_02_10">Section 2.10, Shell Grammar</a>; <newline> is frequently used.</p>
|
|
|
|
<p>A proposal was made to use the <b><do-done></b> construct in all cases where command grouping in the current process
|
|
environment is performed, identifying it as a construct for the grouping commands, as well as for shell functions. This was not
|
|
included because the shell already has a grouping construct for this purpose ( <tt>"{}"</tt> ), and changing it would have been
|
|
counter-productive.</p>
|
|
|
|
<h5><a name="tag_02_02_09_12"></a>For Loop</h5>
|
|
|
|
<p>The format is shown with generous usage of <newline>s. See the grammar in the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001, <a href="../utilities/xcu_chap02.html#tag_02_10">Section 2.10, Shell Grammar</a> for a precise
|
|
description of where <newline>s and semicolons can be interchanged.</p>
|
|
|
|
<p>Some historical implementations support <tt>'{'</tt> and <tt>'}'</tt> as substitutes for <b>do</b> and <b>done</b>. The standard
|
|
developers chose to omit them, even as an obsolescent feature. (Note that these substitutes were only for the <b>for</b> command;
|
|
the <b>while</b> and <b>until</b> commands could not use them historically because they are followed by compound-lists that may
|
|
contain <tt>"{...}"</tt> grouping commands themselves.)</p>
|
|
|
|
<p>The reserved word pair <b>do</b> ... <b>done</b> was selected rather than <b>do</b> ... <b>od</b> (which would have matched the
|
|
spirit of <b>if</b> ... <b>fi</b> and <b>case</b> ... <b>esac</b>) because <a href="../utilities/od.html"><i>od</i></a> is already
|
|
the name of a standard utility.</p>
|
|
|
|
<p>PASC Interpretation 1003.2 #169 has been applied changing the grammar.</p>
|
|
|
|
<h5><a name="tag_02_02_09_13"></a>Case Conditional Construct</h5>
|
|
|
|
<p>An optional left parenthesis before <i>pattern</i> was added to allow numerous historical KornShell scripts to conform. At one
|
|
time, using the leading parenthesis was required if the <b>case</b> statement was to be embedded within a <tt>"$()"</tt> command
|
|
substitution; this is no longer the case with the POSIX shell. Nevertheless, many historical scripts use the left parenthesis, if
|
|
only because it makes matching-parenthesis searching easier in <a href="../utilities/vi.html"><i>vi</i></a> and other editors. This
|
|
is a relatively simple implementation change that is upwards-compatible for all scripts.</p>
|
|
|
|
<p>Consideration was given to requiring <a href="../utilities/break.html"><i>break</i></a> inside the
|
|
<i>compound-list</i> to prevent falling through to the next pattern action list. This was rejected as being nonexisting practice.
|
|
An interesting undocumented feature of the KornShell is that using <tt>";&"</tt> instead of <tt>";;"</tt> as a terminator
|
|
causes the exact opposite behavior-the flow of control continues with the next <i>compound-list</i>.</p>
|
|
|
|
<p>The pattern <tt>'*'</tt> , given as the last pattern in a <b>case</b> construct, is equivalent to the default case in a
|
|
C-language <b>switch</b> statement.</p>
|
|
|
|
<p>The grammar shows that reserved words can be used as patterns, even if one is the first word on a line. Obviously, the reserved
|
|
word <b>esac</b> cannot be used in this manner.</p>
|
|
|
|
<h5><a name="tag_02_02_09_14"></a>If Conditional Construct</h5>
|
|
|
|
<p>The precise format for the command syntax is described in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a
|
|
href="../utilities/xcu_chap02.html#tag_02_10">Section 2.10, Shell Grammar</a>.</p>
|
|
|
|
<h5><a name="tag_02_02_09_15"></a>While Loop</h5>
|
|
|
|
<p>The precise format for the command syntax is described in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a
|
|
href="../utilities/xcu_chap02.html#tag_02_10">Section 2.10, Shell Grammar</a>.</p>
|
|
|
|
<h5><a name="tag_02_02_09_16"></a>Until Loop</h5>
|
|
|
|
<p>The precise format for the command syntax is described in the Shell and Utilities volume of IEEE Std 1003.1-2001, <a
|
|
href="../utilities/xcu_chap02.html#tag_02_10">Section 2.10, Shell Grammar</a>.</p>
|
|
|
|
<h5><a name="tag_02_02_09_17"></a>Function Definition Command</h5>
|
|
|
|
<p>The description of functions in an early proposal was based on the notion that functions should behave like miniature shell
|
|
scripts; that is, except for sharing variables, most elements of an execution environment should behave as if they were a new
|
|
execution environment, and changes to these should be local to the function. For example, traps and options should be reset on
|
|
entry to the function, and any changes to them do not affect the traps or options of the caller. There were numerous objections to
|
|
this basic idea, and the opponents asserted that functions were intended to be a convenient mechanism for grouping common commands
|
|
that were to be executed in the current execution environment, similar to the execution of the <a href=
|
|
"../utilities/dot.html"><i>dot</i></a> special built-in.</p>
|
|
|
|
<p>It was also pointed out that the functions described in that early proposal did not provide a local scope for everything a new
|
|
shell script would, such as the current working directory, or <a href="../utilities/umask.html"><i>umask</i></a>, but instead
|
|
provided a local scope for only a few select properties. The basic argument was that if a local scope is needed for the execution
|
|
environment, the mechanism already existed: the application can put the commands in a new shell script and call that script. All
|
|
historical shells that implemented functions, other than the KornShell, have implemented functions that operate in the current
|
|
execution environment. Because of this, traps and options have a global scope within a shell script. Local variables within a
|
|
function were considered and included in another early proposal (controlled by the special built-in <i>local</i>), but were removed
|
|
because they do not fit the simple model developed for functions and because there was some opposition to adding yet another new
|
|
special built-in that was not part of historical practice. Implementations should reserve the identifier <i>local</i> (as well as
|
|
<i>typeset</i>, as used in the KornShell) in case this local variable mechanism is adopted in a future version of
|
|
IEEE Std 1003.1-2001.</p>
|
|
|
|
<p>A separate issue from the execution environment of a function is the availability of that function to child shells. A few
|
|
objectors maintained that just as a variable can be shared with child shells by exporting it, so should a function. In early
|
|
proposals, the <a href="../utilities/export.html"><i>export</i></a> command therefore had a <b>-f</b> flag for exporting
|
|
functions. Functions that were exported were to be put into the environment as <i>name</i>()= <i>value</i> pairs, and upon
|
|
invocation, the shell would scan the environment for these and automatically define these functions. This facility was strongly
|
|
opposed and was omitted. Some of the arguments against exportable functions were as follows:</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>There was little historical practice. The Ninth Edition shell provided them, but there was controversy over how well it
|
|
worked.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>There are numerous security problems associated with functions appearing in the environment of a user and overriding standard
|
|
utilities or the utilities owned by the application.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>There was controversy over requiring <a href="../utilities/make.html"><i>make</i></a> to import functions, where it has
|
|
historically used an <i>exec</i> function for many of its command line executions.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Functions can be big and the environment is of a limited size. (The counter-argument was that functions are no different from
|
|
variables in terms of size: there can be big ones, and there can be small ones-and just as one does not export huge variables, one
|
|
does not export huge functions. However, this might not apply to the average shell-function writer, who typically writes much
|
|
larger functions than variables.)</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>As far as can be determined, the functions in the Shell and Utilities volume of IEEE Std 1003.1-2001 match those in
|
|
System V. Earlier versions of the KornShell had two methods of defining functions:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>function</tt> <i>fname</i> <tt>{</tt> <i>compound-list</i> <tt>}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>and:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<i>fname</i><tt>() {</tt> <i>compound-list</i> <tt>}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The latter used the same definition as the Shell and Utilities volume of IEEE Std 1003.1-2001, but differed in
|
|
semantics, as described previously. The current edition of the KornShell aligns the latter syntax with the Shell and Utilities
|
|
volume of IEEE Std 1003.1-2001 and keeps the former as is.</p>
|
|
|
|
<p>The name space for functions is limited to that of a <i>name</i> because of historical practice. Complications in defining the
|
|
syntactic rules for the function definition command and in dealing with known extensions such as the <tt>"@()"</tt> usage in the
|
|
KornShell prevented the name space from being widened to a <i>word</i>. Using functions to support synonyms such as the
|
|
<tt>"!!"</tt> and <tt>'%'</tt> usage in the C shell is thus disallowed to conforming applications, but acceptable as an extension.
|
|
For interactive users, the aliasing facilities in the Shell and Utilities volume of IEEE Std 1003.1-2001 should be
|
|
adequate for this purpose. It is recognized that the name space for utilities in the file system is wider than that currently
|
|
supported for functions, if the portable filename character set guidelines are ignored, but it did not seem useful to mandate
|
|
extensions in systems for so little benefit to conforming applications.</p>
|
|
|
|
<p>The <tt>"()"</tt> in the function definition command consists of two operators. Therefore, intermixing <blank>s with the
|
|
<i>fname</i>, <tt>'('</tt> , and <tt>')'</tt> is allowed, but unnecessary.</p>
|
|
|
|
<p>An example of how a function definition can be used wherever a simple command is allowed:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt># If variable i is equal to "yes",
|
|
# define function foo to be ls -l
|
|
#
|
|
[ "$i" = yes ] && foo() {
|
|
ls -l
|
|
}
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h4><a name="tag_02_02_10"></a>Shell Grammar</h4>
|
|
|
|
<p>There are several subtle aspects of this grammar where conventional usage implies rules about the grammar that in fact are not
|
|
true.</p>
|
|
|
|
<p>For <i>compound_list</i>, only the forms that end in a <i>separator</i> allow a reserved word to be recognized, so usually only
|
|
a <i>separator</i> can be used where a compound list precedes a reserved word (such as <b>Then</b>, <b>Else</b>, <b>Do</b>, and
|
|
<b>Rbrace</b>). Explicitly requiring a separator would disallow such valid (if rare) statements as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>if (false) then (echo x) else (echo y) fi
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>See the Note under special grammar rule (1).</p>
|
|
|
|
<p>Concerning the third sentence of rule (1) (``Also, if the parser ..."):</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<p>This sentence applies rather narrowly: when a compound list is terminated by some clear delimiter (such as the closing <b>fi</b>
|
|
of an inner <b>if_clause</b>) then it would apply; where the compound list might continue (as in after a <tt>';'</tt> ), rule (7a)
|
|
(and consequently the first sentence of rule (1)) would apply. In many instances the two conditions are identical, but this part of
|
|
rule (1) does not give license to treating a <b>WORD</b> as a reserved word unless it is in a place where a reserved word has to
|
|
appear.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>The statement is equivalent to requiring that when the LR(1) lookahead set contains exactly one reserved word, it must be
|
|
recognized if it is present. (Here "LR(1)" refers to the theoretical concepts, not to any real parser generator.)</p>
|
|
|
|
<p>For example, in the construct below, and when the parser is at the point marked with <tt>'^'</tt> , the only next legal token is
|
|
<b>then</b> (this follows directly from the grammar rules):</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>if if...fi then ... fi
|
|
^
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>At that point, the <b>then</b> must be recognized as a reserved word.</p>
|
|
|
|
<p>(Depending on the parser generator actually used, "extra" reserved words may be in some lookahead sets. It does not really
|
|
matter if they are recognized, or even if any possible reserved word is recognized in that state, because if it is recognized and
|
|
is not in the (theoretical) LR(1) lookahead set, an error is ultimately detected. In the example above, if some other reserved word
|
|
(for example, <b>while</b>) is also recognized, an error occurs later.</p>
|
|
|
|
<p>This is approximately equivalent to saying that reserved words are recognized after other reserved words (because it is after a
|
|
reserved word that this condition occurs), but avoids the "except for ..." list that would be required for <b>case</b>,
|
|
<b>for</b>, and so on. (Reserved words are of course recognized anywhere a <i>simple_command</i> can appear, as well. Other rules
|
|
take care of the special cases of non-recognition, such as rule (4) for <b>case</b> statements.)</p>
|
|
</li>
|
|
</ul>
|
|
|
|
<p>Note that the body of here-documents are handled by token recognition (see the Shell and Utilities volume of
|
|
IEEE Std 1003.1-2001, <a href="../utilities/xcu_chap02.html#tag_02_03">Section 2.3, Token Recognition</a>) and do not
|
|
appear in the grammar directly. (However, the here-document I/O redirection operator is handled as part of the grammar.)</p>
|
|
|
|
<p>The start symbol of the grammar ( <b>complete_command</b>) represents either input from the command line or a shell script. It
|
|
is repeatedly applied by the interpreter to its input and represents a single "chunk" of that input as seen by the
|
|
interpreter.</p>
|
|
|
|
<h5><a name="tag_02_02_10_01"></a>Shell Grammar Lexical Conventions</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h5><a name="tag_02_02_10_02"></a>Shell Grammar Rules</h5>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h4><a name="tag_02_02_11"></a>Signals and Error Handling</h4>
|
|
|
|
<p>There is no additional rationale provided for this section.</p>
|
|
|
|
<h4><a name="tag_02_02_12"></a>Shell Execution Environment</h4>
|
|
|
|
<p>Some implementations have implemented the last stage of a pipeline in the current environment so that commands such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<i>command</i> <tt>| read foo
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>set variable <b>foo</b> in the current environment. This extension is allowed, but not required; therefore, a shell programmer
|
|
should consider a pipeline to be in a subshell environment, but not depend on it.</p>
|
|
|
|
<p>In early proposals, the description of execution environment failed to mention that each command in a multiple command pipeline
|
|
could be in a subshell execution environment. For compatibility with some historical shells, the wording was phrased to allow an
|
|
implementation to place any or all commands of a pipeline in the current environment. However, this means that a POSIX application
|
|
must assume each command is in a subshell environment, but not depend on it.</p>
|
|
|
|
<p>The wording about shell scripts is meant to convey the fact that describing "trap actions" can only be understood in the
|
|
context of the shell command language. Outside of this context, such as in a C-language program, signals are the operative
|
|
condition, not traps.</p>
|
|
|
|
<h4><a name="tag_02_02_13"></a>Pattern Matching Notation</h4>
|
|
|
|
<p>Pattern matching is a simpler concept and has a simpler syntax than REs, as the former is generally used for the manipulation of
|
|
filenames, which are relatively simple collections of characters, while the latter is generally used to manipulate arbitrary text
|
|
strings of potentially greater complexity. However, some of the basic concepts are the same, so this section points liberally to
|
|
the detailed descriptions in the Base Definitions volume of IEEE Std 1003.1-2001, <a href=
|
|
"../basedefs/xbd_chap09.html">Chapter 9, Regular Expressions</a>.</p>
|
|
|
|
<h5><a name="tag_02_02_13_01"></a>Patterns Matching a Single Character</h5>
|
|
|
|
<p>Both quoting and escaping are described here because pattern matching must work in three separate circumstances:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Calling directly upon the shell, such as in pathname expansion or in a <b>case</b> statement. All of the following match the
|
|
string or file <b>abc</b>:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>abc "abc" a"b"c a\bc a[b]c a["b"]c a[\b]c a["\b"]c a?c a*c
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The following do not:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>"a?c" a\*c a\[b]c
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Calling a utility or function without going through a shell, as described for <a href="../utilities/find.html"><i>find</i></a>
|
|
and the <a href="../functions/fnmatch.html"><i>fnmatch</i>()</a> function defined in the System Interfaces volume of
|
|
IEEE Std 1003.1-2001.</p>
|
|
</li>
|
|
|
|
<li>
|
|
<p>Calling utilities such as <a href="../utilities/find.html"><i>find</i></a>, <i>cpio</i>, <i>tar</i>, or <a href=
|
|
"../utilities/pax.html"><i>pax</i></a> through the shell command line. In this case, shell quote removal is performed before the
|
|
utility sees the argument. For example, in:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>find /bin -name "e\c[\h]o" -print
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>after quote removal, the backslashes are presented to <a href="../utilities/find.html"><i>find</i></a> and it treats them as
|
|
escape characters. Both precede ordinary characters, so the <i>c</i> and <i>h</i> represent themselves and <a href=
|
|
"../utilities/echo.html"><i>echo</i></a> would be found on many historical systems (that have it in <b>/bin</b>). To find a
|
|
filename that contained shell special characters or pattern characters, both quoting and escaping are required, such as:</p>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<tt>pax -r ... "*a\(\?"
|
|
</tt>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>to extract a filename ending with <tt>"a(?"</tt> .</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>Conforming applications are required to quote or escape the shell special characters (sometimes called metacharacters). If used
|
|
without this protection, syntax errors can result or implementation extensions can be triggered. For example, the KornShell
|
|
supports a series of extensions based on parentheses in patterns.</p>
|
|
|
|
<p>The restriction on a circumflex in a bracket expression is to allow implementations that support pattern matching using the
|
|
circumflex as the negation character in addition to the exclamation mark. A conforming application must use something like
|
|
<tt>"[\^!]"</tt> to match either character.</p>
|
|
|
|
<h5><a name="tag_02_02_13_02"></a>Patterns Matching Multiple Characters</h5>
|
|
|
|
<p>Since each asterisk matches zero or more occurrences, the patterns <tt>"a*b"</tt> and <tt>"a**b"</tt> have identical
|
|
functionality.</p>
|
|
|
|
<h5><a name="tag_02_02_13_03"></a>Examples</h5>
|
|
|
|
<dl compact>
|
|
<dt><tt>a[bc]</tt></dt>
|
|
|
|
<dd>Matches the strings <tt>"ab"</tt> and <tt>"ac"</tt> .</dd>
|
|
|
|
<dt><tt>a*d</tt></dt>
|
|
|
|
<dd>Matches the strings <tt>"ad"</tt> , <tt>"abd"</tt> , and <tt>"abcd"</tt> , but not the string <tt>"abc"</tt> .</dd>
|
|
|
|
<dt><tt>a*d*</tt></dt>
|
|
|
|
<dd>Matches the strings <tt>"ad"</tt> , <tt>"abcd"</tt> , <tt>"abcdef"</tt> , <tt>"aaaad"</tt> , and <tt>"adddd"</tt> .</dd>
|
|
|
|
<dt><tt>*a*d</tt></dt>
|
|
|
|
<dd>Matches the strings <tt>"ad"</tt> , <tt>"abcd"</tt> , <tt>"efabcd"</tt> , <tt>"aaaad"</tt> , and <tt>"adddd"</tt> .</dd>
|
|
</dl>
|
|
|
|
<h5><a name="tag_02_02_13_04"></a>Patterns Used for Filename Expansion</h5>
|
|
|
|
<p>The caveat about a slash within a bracket expression is derived from historical practice. The pattern <tt>"a[b/c]d"</tt> does
|
|
not match such pathnames as <b>abd</b> or <b>a/d</b>. On some implementations (including those conforming to the Single UNIX
|
|
Specification), it matched a pathname of literally <tt>"a[b/c]d"</tt> . On other systems, it produced an undefined condition (an
|
|
unescaped <tt>'['</tt> used outside a bracket expression). In this version, the XSI behavior is now required.</p>
|
|
|
|
<p>Filenames beginning with a period historically have been specially protected from view on UNIX systems. A proposal to allow an
|
|
explicit period in a bracket expression to match a leading period was considered; it is allowed as an implementation extension, but
|
|
a conforming application cannot make use of it. If this extension becomes popular in the future, it will be considered for a future
|
|
version of the Shell and Utilities volume of IEEE Std 1003.1-2001.</p>
|
|
|
|
<p>Historical systems have varied in their permissions requirements. To match <b>f*/bar</b> has required read permissions on the
|
|
<b>f*</b> directories in the System V shell, but the Shell and Utilities volume of IEEE Std 1003.1-2001, the C
|
|
shell, and KornShell require only search permissions.</p>
|
|
|
|
<h4><a name="tag_02_02_14"></a>Special Built-In Utilities</h4>
|
|
|
|
<p>See the RATIONALE sections on the individual reference pages.</p>
|
|
|
|
|
|
<hr size="2" noshade>
|
|
<center><font size="2"><!--footer start-->
|
|
UNIX ® is a registered Trademark of The Open Group.<br>
|
|
POSIX ® is a registered Trademark of The IEEE.<br>
|
|
[ <a href="../mindex.html">Main Index</a> | <a href="../basedefs/contents.html">XBD</a> | <a href=
|
|
"../utilities/contents.html">XCU</a> | <a href="../functions/contents.html">XSH</a> | <a href="../xrat/contents.html">XRAT</a>
|
|
]</font></center>
|
|
|
|
<!--footer end-->
|
|
<hr size="2" noshade>
|
|
</body>
|
|
</html>
|
|
|