Почему $ {$ #} возвращает тот же результат, что и $$ в оболочке?

18

Пытаясь получить последний набор позиционных параметров /bin/dash, я пытался echo ${$#}. Удивительно, но это привело не к ошибке, а к PID, который совпадает с $$содержимым переменной. Вопрос, почему этот синтаксис работает? Какое синтаксическое правило применяется к этой оболочке?

В основном то, что я сделал, это

$ 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 Нет ожиданий. Я пытался другие символы рядом #и %и какие результаты поведения от тех.
Сергей Колодяжный
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Конечно, могут возникнуть потенциальные проблемы, подумайте, в какой степени - это другая тема. Но да, это вариант
Сергей Колодяжный

Ответы:

35

Это $$ с удаленным пустым префиксом :

${parameter#[word]}

Удалите самый маленький образец префикса . Слово должно быть расширено , чтобы получить шаблон. Расширение параметра должно затем привести к параметру с наименьшей частью префикса, совпадающей с удаленным шаблоном. Если присутствует, слово не должно начинаться с кавычек #.

То же самое относится к %(суффикс). @и *не являются модификаторами расширения параметров, поэтому они являются ошибками. Бывало для $?, $-или гипотетический , $=а также. ${$+}это пустое расширение.

Майкл Гомер
источник
Я должен был распознать замену параметра немедленно там. Хороший улов.
Сергей Колодяжный