Auf Asche, Dash und Bash, wenn ich renne
$ echo ab$
es kehrt zurück
ab$
Wird dieses Verhalten von POSIX spezifiziert oder ist es nur eine übliche Konvention in POSIX-kompatiblen Shells? Auf der Seite POSIX Shell Command Language konnte nichts gefunden werden, das dieses Verhalten erwähnt.
$
gewinnt eine besondere Bedeutung , wenn es das letzte Zeichen in einem Wort?“ Es ist keine einzige spezielle Bedeutung zugeordnet$
; Es wird verwendet, um mehrere, aber unterschiedliche Erweiterungen wie Parametererweiterungen${...}
, Befehlssubstitutionen$(...)
und arithmetische Ausdrücke einzuführen$((...))
. Einige Shells führen zusätzliche Kontexte ein, z. B.ksh
die Befehlsersetzungsvariantex=${ echo foo; echo bar;}
(die sich vom Standard$(...)
dadurch unterscheidet, dass die Befehle nicht in einer Subshell ausgeführt werden).ab$
folgt also kein Zeichen$
, unabhängig davon, ob ein Nullzeichen in der ursprünglichen Eingabezeichenfolge oder ein Leerzeichen in einer Groß- / Kleinschreibung "gefolgt" wurde mögenecho ab$ foo
; Das ursprüngliche Leerzeichen ohne Anführungszeichen wurde erkannt und nach dem Parsen verworfen.Antworten:
$
nicht eine besondere Bedeutung für sich allein hat (Versuchecho $
), nur wenn sie mit anderem Charakter kombiniert , nachdem sie und eine Erweiterung bilden, zum Beispiel$var
(oder${var}
)$(util)
,$((1+2))
.Das
$
bekommt seine "besondere" Bedeutung als Definition einer Erweiterung im POSIX-Standard unter dem Abschnitt Tokenerkennung :Wenn sich
$
also keine Erweiterung bildet, werden andere Parsing-Regeln wirksam:Das deckt deine
ab$
Saite ab.Im Falle eines Einzelnen
$
(das "neue Wort" wäre das$
für sich):Die Bedeutung des generierten Wortes, das eine
$
nicht standardmäßige Erweiterung enthält , wird von POSIX explizit als nicht angegeben definiert.Beachten Sie auch, dass dies
$
das letzte Zeichen in$$
ist, dies jedoch auch die Variable ist, die die PID der aktuellen Shell enthält. Inbash
,!$
kann eine Verlaufserweiterung aufrufen (das letzte Argument des vorherigen Befehls). Nein, im Allgemeinen$
ist es nicht ohne Bedeutung am Ende eines nicht zitierten Wortes, aber am Ende eines Wortes bedeutet es zumindest keine Standarderweiterung.quelle
Abhängig von der genauen Situation ist dies entweder explizit nicht spezifiziert (so dass Implementierungen möglicherweise so funktionieren, wie sie es wollen) oder es muss geschehen, wie Sie es beobachtet haben. In Ihrem genauen Szenario
echo ab$
, beauftragt POSIX die Ausgabe „ab $“ , dass Sie beobachtet und es ist nicht nicht näher bezeichnet . Eine kurze Zusammenfassung aller verschiedenen Fälle ist am Ende.Es gibt zwei Elemente: erst das Tokenisieren in Wörter und dann die Interpretation dieser Wörter.
Tokenisierung
Die POSIX-Tokenisierung erfordert, dass a
$
nicht der Beginn einer gültigen Parametererweiterung , einer Befehlssubstitution oder einer arithmetischen Substitution ist , um als wörtlicher Teil des zu erstellendenWORD
Tokens betrachtet zu werden. Dies liegt daran, dass Regel 5 ("Wenn das aktuelle Zeichen nicht in Anführungszeichen$
oder steht`
, identifiziert die Shell den Beginn von Kandidaten für Parametererweiterung, Befehlssubstitution oder arithmetische Erweiterung anhand ihrer einleitenden nicht in Anführungszeichen stehenden Zeichenfolgen:$
oder${
,$(
oder`
, und$((
bzw.") ) entfällt, da dort keine dieser Erweiterungen realisierbar ist. Für die Parametererweiterung muss ein gültiger Name angegeben werden, und ein leerer Name ist ungültig.Da diese Regel nicht galt, folgen wir weiter, bis wir eine finden, die dies tut. Die beiden Kandidaten sind # 8 ("Wenn das vorherige Zeichen Teil eines Wortes war, wird das aktuelle Zeichen an dieses Wort angehängt.") Und # 10 ("Das aktuelle Zeichen wird als Anfang eines neuen Wortes verwendet."). , die gelten für
echo a$
undecho $
verbunden.Es gibt auch einen dritten Fall des Formulars
echo a$+b
der durch denselben Riss fällt, da+
es sich nicht um den Namen eines speziellen Parameters handelt. Auf diesen werden wir später zurückkommen, da er verschiedene Teile der Regeln auslöst.Die Spezifikation verlangt daher, dass die
$
Wort syntaktisch als Teil des Wortes betrachtet und später weiterverarbeitet werden kann.Worterweiterung
Nachdem die Eingabe auf diese Weise analysiert wurde, werden mit dem
$
im Wort enthaltenen Wort Worterweiterungen auf jedes der gelesenen Wörter angewendet. Jedes Wort wird einzeln verarbeitet .Es wird angegeben, dass :
"Nicht spezifiziert" ist hier ein besonderer Begriff, der dies bedeutet
In Ihrem Beispiel
echo ab$
, das$
nicht durch , gefolgt jeden Charakter , so dass diese Regel nicht gilt und die nicht näher bezeichnet Ergebnis wird nicht aufgerufen. Es gibt einfach keine Erweiterung, die von der$
, so dass sie buchstäblich vorhanden und ausgedruckt ist.Wo es würde gelten in unserem dritten Fall von oben:
echo a$+b
. Hier$
wird , gefolgt von+
, die nicht eine Zahl ist , spezieller Parameter (@
,*
,#
,?
,-
,$
,!
, oder0
), Start eines variablen Namen (Strich oder eine alphabetischen vom tragbaren Zeichensatz ), oder eine der Klammern. In diesem Fall ist das Verhalten nicht angegeben: Eine konforme Shell darf einen speziellen Parameter erfinden, der+
zum Erweitern aufgerufen wird , und eine konforme Anwendung sollte nicht davon ausgehen, dass die Shell dies nicht tut . Die Shell könnte auch alles andere tun, einschließlich der Meldung eines Fehlers.Zum Beispiel interpretiert
$+b
b
zsh, auch im POSIX-Modus, als "is variable set" und setzt entweder 1 oder 0 an seine Stelle. Es hat auch Erweiterungen für~
und=
. Das ist konformes Verhalten.Ein anderer Ort, an dem dies passieren könnte, ist
echo "a$ b"
. Auch hier darf die Shell tun, was sie will, und Sie als Autor des Skripts sollten die Option "$
Wenn Sie eine wörtliche Ausgabe wünschen" umgehen. Wenn Sie dies nicht tun, funktioniert es möglicherweise, aber Sie können sich nicht darauf verlassen. Dies ist der absolute Buchstabe der Spezifikation, aber ich glaube nicht, dass diese Art von Granularität beabsichtigt oder in Betracht gezogen wurde.in Summe
echo ab$
: Literalausgabe, vollständig spezifiziertecho a$ b
: Literalausgabe, vollständig spezifiziertecho a$ b$
: Literalausgabe, vollständig spezifiziertecho a$b
: Erweiterung des Parametersb
, vollständig spezifiziertecho a$-b
: Erweiterung spezieller Parameter-
, vollständig spezifiziertecho a$+b
: unspezifiziertes Verhaltenecho "a$ b"
: unspezifiziertes VerhaltenFür ein
$
am Ende eines Wortes darf man sich auf das Verhalten verlassen und es muss wörtlich behandelt undecho
als Teil seines Arguments an den Befehl weitergegeben werden. Dies ist eine Konformitätsanforderung an die Shell.quelle
echo $
auch wörtlich und vollständig spezifiziert?echo "$"
undecho "a b$"
fallen?