在跑步时在灰,破折号和bash上
$ echo ab$
它返回
ab$
这种行为是由POSIX指定的,还是在POSIX兼容的shell中只是常见的约定?我在POSIX Shell命令语言页面上找不到任何提及此行为的信息。
ab$
,没有字符跟随$
,无论它是“跟随”原始输入字符串中的空字符还是用空格分隔喜欢echo ab$ foo
; 原始未加引号的空格已在解析后被识别并丢弃。
在跑步时在灰,破折号和bash上
$ echo ab$
它返回
ab$
这种行为是由POSIX指定的,还是在POSIX兼容的shell中只是常见的约定?我在POSIX Shell命令语言页面上找不到任何提及此行为的信息。
ab$
,没有字符跟随$
,无论它是“跟随”原始输入字符串中的空字符还是用空格分隔喜欢echo ab$ foo
; 原始未加引号的空格已在解析后被识别并丢弃。
Answers:
$
echo $
仅当其后与其他字符组合并形成扩展符$var
(例如,,${var}
)时,它本身并没有特殊含义(try )。$(util)
$((1+2))
的$
“特殊”含义是在“ 令牌识别 ”部分下定义POSIX标准的扩展:
如果当前字符是一个无引号
$
或`
:,外壳应确定任何候选参数扩展,命令替换,或从它们的介绍性无引号字符序列算术扩展的开始$
或${
,$(
或`
,和$((
分别。外壳应读取足够的输入以确定要扩展的单元的末端(如引用部分中所述))。在处理字符时,如果发现替换中嵌套了扩展或引号的实例,则外壳程序应以为找到的结构指定的方式递归处理它们。从替换开始到结束为止发现的字符,允许进行任何识别嵌入式构造的必要递归,都应未经修改地包含在结果标记中,包括任何嵌入式或封闭的替换运算符或引号。令牌不得在替换结束时定界。
因此,如果$
不构成扩展,则其他解析规则将生效:
如果前一个字符是单词的一部分,则当前字符应附加到该单词的后面。
那涵盖了你的ab$
字符串。
在孤独的情况下$
(“新词” $
本身就是“” ):
当前字符用作新单词的开头。
POSIX未明确定义所生成的包含非标准扩展名的单词的含义$
。
还要注意,这$
是中的最后一个字符$$
,但这也恰好是保存当前shell的PID的变量。在中bash
,!$
可以调用历史记录扩展(上一个命令中的最后一个参数)。因此,总的来说,没有,$
在未加引号的单词的末尾并非没有含义,但是在单词的末尾,它至少并不表示标准扩展。
根据实际情况,这可能是未明确指定的(因此实现可能会按其意愿进行),也可能需要按照您观察到的那样进行。在您的实际情况下echo ab$
,POSIX会强制您观察到输出“ ab $”,并且该输出并非未指定。最后是所有不同情况的快速摘要。
有两个元素:首先标记为单词,然后解释这些单词。
POSIX断词要求一个$
是不是一个有效的起始参数扩展,命令替换,或算术取代被认为是的文本部分WORD
构造令牌之中。这是因为,规则5(“如果当前字符是一个无引号$
或`
,壳必从介绍无引号字符序列识别任何候选参数扩展,命令替换,或算术膨胀开始:$
或${
,$(
或`
,和$((
,分别为” )不适用,因为这些扩展均不可行。参数扩展要求在其中显示有效名称,并且无效名称无效。
由于该规则不适用,因此我们会继续遵循,直到找到一个适用的规则。两个候选者是#8(“如果先前的字符是单词的一部分,则当前字符应附加到该单词。”)和#10(“当前的字符用作新单词的开头”。) ,分别适用于echo a$
和echo $
。
echo a$+b
由于+
不是特殊参数的名称,因此也存在第三种情况,即同一形式的裂纹。我们将在稍后返回到这一条,因为它会触发规则的不同部分。
因此,该规范要求在$
语法上将其视为单词的一部分,然后可以在以后进行进一步处理。
以这种方式解析输入后$
,单词中将包含单词,单词扩展将应用于已读取的每个单词。每个单词都是单独处理的。
规定:
如果未加引号的“ $”后面跟有以下字符之一,则该字符不是:
- 数字字符
- 特殊参数之一的名称(请参阅特殊参数)
- 变量名的有效第一个字符
- A
<left-curly-bracket>
('{')- 一种
<left-parenthesis>
结果不确定。
“未指定”是此处的特定术语,表示
在你的榜样,echo ab$
中,$
后面没有任何字符,所以这条规则不适用,未指定的结果不会被调用。根本没有引起的扩展$
,因此它确实存在并已打印出来。
它会应用在我们的第三种情况从上面:echo a$+b
。这里$
后面是+
,这不是数字,特殊参数(@
,*
,#
,?
,-
,$
,!
,或0
),启动一可变的名称(下划线或从字母便携式字符集),或支架中的一个。在这种情况下,行为是不确定的:允许+
合格的shell 发明一个称为expand 的特殊参数,合格的应用程序不应假定shell不能这样做。外壳程序还可以执行其喜欢的其他任何操作,包括报告错误。
例如,zsh(包括其POSIX模式)被解释$+b
为“是变量b
集”,并在其位置替换1或0。类似地,它还有~
和的扩展名=
。这是合规的行为。
这可能发生的另一个地方是echo "a$ b"
。再次,shell被允许按照其意愿进行操作,并且$
如果您要文字输出,则作为脚本作者的您应转义。如果不这样做,它可能会起作用,但您不能依靠它。这是规范的绝对字母,但是我不认为这种粒度是预期或考虑的。
echo ab$
:文字输出,完全指定echo a$ b
:文字输出,完全指定echo a$ b$
:文字输出,完全指定echo a$b
:参数扩展b
,完全指定echo a$-b
:扩展特殊参数-
,完全指定echo a$+b
:未指定的行为echo "a$ b"
:未指定的行为对于$
单词结尾的a,允许您依赖该行为,并且必须对其进行字面上的处理,并将echo
其作为参数的一部分传递给命令。这是对外壳的一致性要求。
echo $
还会是字面意义并完全指定吗?
echo "$"
和echo "a b$"
下跌呢?
$
获得特殊含义?” 没有分配任何单一的特殊含义$
;它用于引入多个但截然不同的扩展,例如参数扩展${...}
,命令替换$(...)
和算术表达式$((...))
。一些shell引入了其他上下文,例如ksh
的command-substitution变体x=${ echo foo; echo bar;}
(与标准不同,它$(...)
不执行subshell中的命令)。