为什么$ {$#}在shell中返回与$$相同的结果?


18

在尝试设置最后一个位置参数时/bin/dash,我已经尝试过了echo ${$#}。出人意料的是,这不会导致错误,但会导致PID与$$变量内容相同。问题,为什么该语法起作用?shell在这里应用的语法规则是什么?

基本上,我所做的是

$ set 1 2 3 4 5
$ echo ${$#}
13819
$ echo $$
13819

显然,%在这种结构中字符也被忽略

$ echo ${$%}
13819

但是*@导致不良的替换错误:

$ echo ${$*}
sh: 10: Bad substitution
$ echo ${$@}
sh: 11: Bad substitution

3
您期待什么${$*}${$@}产生什么?
库萨兰达

2
@Kusalananda没有期望。我正在尝试其他字符#%以及这些字符会导致什么行为。
Sergiy Kolodyazhnyy

1
要在Dash中进行间接操作,请使用eval,例如dash -c 'set 1 2 3 4 5; eval "echo \$$#"'。来源:Ubuntu Wiki
wjandrea

1
@wjandrea是的,已经知道那个了。实际上,已经有一个问题:stackoverflow.com/questions/1853946/… 我试图自己找到一种方法,而没有先阅读问题(而且我已经知道for i; do true; done最后一项$i),但是我正在寻找更优雅的方法。eval当然,考虑到什么程度也可能存在潜在问题-这是另一个主题。但是是的,这是一个选择
Sergiy Kolodyazhnyy

Answers:


35

这是$$ 一个空前缀删除

${parameter#[word]}

删除最小前缀模式。该将被扩展为一个模式。然后,参数扩展将导致parameter,其中前缀的最小部分被模式删除而匹配。如果存在的话,单词不应以不带引号的开头#

这同样适用于%(后缀)。@并且*不是参数扩展修饰符,因此它们是错误的。它会发生的$?$-或假设$=为好。${$+}是一个空的扩展。


我应该在那里立即识别参数替换。接得好。
Sergiy Kolodyazhnyy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.