📄 xcu_chap02.html
字号:
<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 itscomplexity 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. Sincethis is not historical practice, it has been left for future implementations to evaluate. (The description in the Shell andUtilities 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-compatiblewith the Bourne shell, which does not determine the closing <tt>'}'</tt> until the word is expanded. The advantage of this is thatincomplete 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 inother 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 ismore 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. Forexample:</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 thatinclude backquotes. For example, these otherwise valid embedded scripts do not work in the left column, but do work on theright:</p><blockquote><pre><tt>echo ` echo $(cat <<\eof cat <<\eofa 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 applicationsthat 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 thecommand 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 scriptsrelying 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 anyambiguities with arithmetic expansion.</p><p>IEEE Std 1003.1-2001/Cor 1-2002, item XCU/TC1/D6/4 is applied, changing the text from: "If a command substitutionoccurs inside double-quotes, it shall not be performed on the results of the substitution." to: "If a command substitution occursinside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.". Thereplacement text taken from the ISO POSIX-2:1993 standard is clearer about the items that are not performed.</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 therewas a strong desire for some kind of arithmetic evaluator to replace <a href="../utilities/expr.html"><i>expr</i></a>, and thatrelating it to <tt>'$'</tt> makes it work well with the standard shell language, and it provides access to arithmetic evaluation inplaces 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 apure arithmetic evaluator of constants and operators (excluding assignment) and represents a simple subset of the previousarithmetic language (which was derived from the KornShell <tt>"(())"</tt> construct). The syntax was changed from that of a commanddenoted 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 arithmeticincluded that it was too complicated, did not fit in well with the use of variables in the shell, and its syntax conflicted withsubshells. The justification for the new syntax is that the shell is traditionally a macro language, and if a new feature is to beadded, it should be accomplished by extending the capabilities presented by the current model of the shell, rather than byinventing a new one outside the model; adding a new dollar expansion was perceived to be the most intuitive and least destructiveway 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 currenttext, but objections were lodged that the 1988 KornShell had already implemented <tt>"$(())"</tt> and there was no compellingreason 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 inthe KornShell.</p><p>It was concluded that the <a href="../utilities/test.html"><i>test</i></a> command ( <b>[</b>) was sufficient for the majorityof relational arithmetic tests, and that tests involving complicated relational expressions within the shell are rare, yet couldstill be accommodated by testing the value of <tt>"$(())"</tt> itself. For example:</p><blockquote><pre><tt># a complicated relational expressionwhile [ $(( (($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 calculationsdone</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> wouldexit true only if the argument was non-zero, and <a href="../utilities/false.html"><i>false</i></a> would exit false only if theargument 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 acommand substitution of a utility named <tt>"2+2"</tt> in a subshell. The standard developers considered this to be obscure andisolated to some KornShell scripts (because <tt>"$()"</tt> command substitution existed previously only in the KornShell). The texton 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 thatthey 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 adjacentparentheses 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 withhigher 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 theimplementation.</p><p>Implementations are also allowed to perform floating-point evaluations as long as an application won't see different results forexpressions that would not overflow <b>signed long</b> integer expression evaluation. (This includes appropriate truncation ofresults 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 sinceonly signed integer arithmetic was required. Since all arithmetic expressions were treated as handling <b>signed long</b> integertypes anyway, the <tt>l</tt> and <tt>L</tt> suffixes were redundant. No known scripts used them and some historic shells did notsupport 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 allof 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, characterconstants 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, noknown shells supported them. Changes made in response to IEEE PASC Interpretation 1003.2 #208 removed the requirement to supportthem (if they were indeed required before). IEEE Std 1003.1-2001 clearly does not require support for characterconstants.</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 splitswords, but it is incompatible with other common versions of the shell. However, each has merit, and so a decision was made to allowboth. If the <i>IFS</i> variable is unset or is <space> <tab> <newline>, the operation is equivalent to the waythe System V shell splits words. Using characters outside the <space> <tab> <newline> set yields theKornShell behavior, where each of the non- <space> <tab> <newline>s is significant. This behavior, which affordsthe most flexibility, was taken from the way the original <a href="../utilities/awk.html"><i>awk</i></a> handled fieldsplitting.</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. Anystring matching that ERE delimits a field, except that the <i>s</i>+ form does not delimit fields at the beginning or the end of aline. 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>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -