Warum gibt $ {$ #} dasselbe Ergebnis wie $$ in der Shell zurück?

18

Bei dem Versuch, den letzten Positionsparameter einzustellen /bin/dash, habe ich es versucht echo ${$#}. Überraschenderweise führte dies nicht zu einem Fehler, sondern zu einer PID, die mit $$variablen Inhalten identisch ist. Frage, warum hat diese Syntax funktioniert? Welche Syntaxregel hat die Shell hier angewendet?

Grundsätzlich habe ich getan

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

Anscheinend wird der %Charakter in einem solchen Konstrukt auch ignoriert

$ echo ${$%}
13819

Aber *und das @führt zu einem schlechten Substitutionsfehler:

$ echo ${$*}
sh: 10: Bad substitution
$ echo ${$@}
sh: 11: Bad substitution
Sergiy Kolodyazhnyy
quelle
3
Was erwarten ${$*}und ${$@}produzieren Sie?
Kusalananda
2
@ Kusalananda Keine Erwartungen. Ich habe andere Charaktere neben #und ausprobiert %und welches Verhalten daraus resultiert.
Sergiy Kolodyazhnyy
1
Um eine Indirektion in Dash durchzuführen, verwenden Sie evalz dash -c 'set 1 2 3 4 5; eval "echo \$$#"'. Quelle: Ubuntu Wiki
wjandrea
1
@wjandrea Yep, das weiß ich schon. Es gibt tatsächlich bereits eine Frage dazu: stackoverflow.com/questions/1853946/… Ich habe versucht, eine Methode selbst zu finden, ohne die Frage zuerst gelesen zu haben (und ich wusste bereits, dass for i; do true; doneich das letzte Element bearbeiten musste$i ), habe aber nach etwas Eleganterem gesucht. evalNatürlich kann es potenzielle Probleme geben, inwieweit gedacht - das ist ein anderes Thema. Aber ja, es ist eine Option
Sergiy Kolodyazhnyy

Antworten:

35

Dies ist $$ mit einem leeren Präfix entfernt :

${parameter#[word]}

Kleinstes Präfixmuster entfernen . Das Wort soll zu einem Muster erweitert werden. Die Parametererweiterung ergibt dann einen Parameter , wobei der kleinste Teil des Präfixes mit dem gelöschten Muster übereinstimmt. Wenn vorhanden, darf das Wort nicht mit einem nicht zitierten beginnen #.

Gleiches gilt für %(Suffix). @und *sind keine Parametererweiterungsmodifikatoren, daher handelt es sich um Fehler. Es würde passieren , für $?, $-oder eine hypothetische $=als auch. ${$+}ist eine leere Erweiterung.

Michael Homer
quelle
Dort hätte ich die Parametersubstitution sofort erkennen müssen. Guter Fang.
Sergiy Kolodyazhnyy