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 erstellenden WORD
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ürecho a$
und echo $
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 :
Wenn auf ein '$' ohne Anführungszeichen ein Zeichen folgt, das nicht eines der folgenden ist:
- Ein numerisches Zeichen
- Der Name eines der Spezialparameter (siehe Spezialparameter )
- Ein gültiges erstes Zeichen eines Variablennamens
- A
<left-curly-bracket>
('{')
- EIN
<left-parenthesis>
Das Ergebnis ist nicht angegeben.
"Nicht spezifiziert" ist hier ein besonderer Begriff, der dies bedeutet
- Eine konforme Shell kann in diesem Fall ein beliebiges Verhalten wählen
- Eine konforme Anwendung kann sich nicht auf ein bestimmtes Verhalten stützen
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 ( @
, *
, #
, ?
, -
, $
, !
, oder 0
), 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 spezifiziert
echo a$ b
: Literalausgabe, vollständig spezifiziert
echo a$ b$
: Literalausgabe, vollständig spezifiziert
echo a$b
: Erweiterung des Parameters b
, vollständig spezifiziert
echo a$-b
: Erweiterung spezieller Parameter -
, vollständig spezifiziert
echo a$+b
: unspezifiziertes Verhalten
echo "a$ b"
: unspezifiziertes Verhalten
Für ein $
am Ende eines Wortes darf man sich auf das Verhalten verlassen und es muss wörtlich behandelt und echo
als Teil seines Arguments an den Befehl weitergegeben werden. Dies ist eine Konformitätsanforderung an die Shell.
$
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).