Manchmal sehe ich Skripte alle diese verschiedenen Arten verwenden von einem Text zu zitieren: "..."
, '...'
, $'...'
, und $"..."
. Warum werden so viele verschiedene Arten von Zitaten verwendet?
Verhalten sie sich anders oder beeinflussen sie, was ich in ihnen tun kann?
Antworten:
All dies bedeutet etwas anderes, und Sie können verschiedene Dinge in sie schreiben (oder die gleichen Dinge mit unterschiedlicher Bedeutung). Unterschiedliche Arten von Anführungszeichen interpretieren unterschiedliche Escape-Sequenzen in ihnen (
\something
) oder lassen variable Interpolationen ($something
) und andere Arten von Erweiterungen in ihnen zu oder lassen diese nicht zu .Zusamenfassend:
'...'
ist ganz wörtlich."..."
erlaubt sowohl Variablen als auch eingebettete Anführungszeichen.$'...'
führt Zeichenausbrüche wie aus\n
, erweitert aber keine Variablen.$"..."
ist für menschlichsprachige Übersetzungen in Bash und ksh.'Einzelzitate'
Was immer Sie zwischen einfachen Anführungszeichen schreiben, wird buchstäblich behandelt und überhaupt nicht verarbeitet. Backslashes und Dollarzeichen haben dort keine besondere Bedeutung. Dies bedeutet, dass Sie ein Zeichen (einschließlich anderer einfacher Anführungszeichen!) Nicht mit einem umgekehrten Schrägstrich versehen, eine Variable nicht interpolieren oder keine andere Shell-Funktion verwenden können.
Alle diese Beispiele führen buchstäblich dazu, was zwischen den Anführungszeichen steht:
Das letzte ist kompliziert - es gibt zwei einfach zitierte Zeichenfolgen, die zusammen mit nicht zitiertem Text ausgeführt werden. Der erste enthält
I\
. Der nicht indn\'t
Anführungszeichen gesetzte Text enthält ein einfaches Anführungszeichen, das auf Shell-Ebene maskiert wird , sodass keine in Anführungszeichen gesetzte Zeichenfolge beginnt und als literales Zeichen (also,dn't
) enthalten ist. Die endgültige Anführungszeichenfolge ist nurve
. All diese Elemente werden auf die übliche Art und Weise, wie die Shell funktioniert, zu einem einzigen Wort zusammengefasst.Eine etwas gebräuchliche Redewendung zum Kombinieren von wörtlichem Text und Variablen besteht darin, sie wie folgt zusammenzuführen:
wird darin enden, dass
als ein einzelnes Wort (besser doppelte Anführungszeichen
$PATH
als auch für alle Fälle - Leerzeichen oder Globbing Zeichen in der Variablen Wert kann auf andere Weise bearbeitet werden - aber im Interesse eines lesbaren Lauf Beispiel habe ich nicht)."Anführungszeichen"
Innerhalb von doppelten Anführungszeichen werden zwei Arten von Erweiterungen verarbeitet, und Sie können einen Backslash verwenden, um Zeichen zu maskieren, um zu verhindern, dass Erweiterungen oder Maskierungen verarbeitet werden.
Es gibt zwei Kategorien von Erweiterungen, die in doppelten Anführungszeichen stehen:
$
( Parametererweiterung$abc
und${abc}
, Befehlssubstitution$(...)
und arithmetische Erweiterung$((...))
) beginnen;`abc`
;Innerhalb der Anführungszeichen kann ein Backslash diese Erweiterungen verhindern, indem er vor das
$
oder gesetzt wird`
. Es kann auch vor einem schließenden doppelten Anführungszeichen stehen, also\"
nur"
in Ihrer Zeichenfolge oder einem anderen Backslash. Jeder andere Backslash bleibt buchstäblich erhalten - es gibt keine Escapezeichen, um andere Zeichen zu erzeugen, und er wird nicht entfernt.Einige dieser Beispiele verhalten sich anders als zuvor, andere nicht:
$ 'ANSI-C quoting'
Diese Art von Anführungszeichen ermöglicht die Verarbeitung von Backslash-Escape-Zeichen im C-Stil, jedoch keine eingebetteten Variablen oder Substitutionen. Es ist die einzige Art des Zitierens, die Zeichenflucht unterstützt .
Dies ist eine Erweiterung von ksh, die jetzt auch in Bash, zsh und einigen anderen Shells unterstützt wird. Es ist noch nicht Teil des POSIX-Standards und daher können maximal portierbare Skripte es nicht verwenden, aber ein Bash- oder ksh-Skript ist kostenlos.
Alle diese Fluchten können mit ihren C Bedeutungen verwendet werden:
\a
,\b
,\f
,\n
,\r
,\t
,\v
, und die wörtliche entweicht\\
,\'
,\"
, und\?
. Sie unterstützen auch die Erweiterungen\e
(Escape-Zeichen) und in Bash und ksh\cx
(was durch Strg-x eingegeben werden würde , z. B.\cM
Wagenrücklauf). Shells haben eine Reihe eigener Nebenstellen.Es erlaubt auch vier Arten von generischen Zeichen zu entkommen:
\nnn
Ein einzelnes Byte mit dem Oktalwert nnn\xHH
ein einzelnes Byte mit Hexadezimalwert HH\uHHHH
, der Unicode-Codepunkt, dessen Hexadezimalindex HHHH ist\UHHHHHHHH
, der Unicode-Codepunkt, dessen Hexadezimalindex HHHHHHHH istAlle diese Ziffern sind nach der ersten optional.
$
und`
haben keine Bedeutung und werden buchstäblich beibehalten, sodass Sie dort keine Variable einfügen können.Die meisten dieser Fluchten Sie simulieren können mit dem
printf
Befehl , obwohl POSIX erfordert nur\\
,\a
,\b
,\f
,\n
,\r
,\t
,\v
, und\nnn
an der Arbeit dort. Sie können Befehls Substitution einzubetten , eine Verwendungprintf
in doppelte Anführungszeichen , wenn erforderlich:"Path:$(printf '\t')$PATH"
.$ "Gebietsschema-Übersetzung"
Dies ist eine ksh- und Bash-spezifische Erweiterung zum Lokalisieren von Textzeichenfolgen in natürlicher Sprache und schlägt den Teil in den Anführungszeichen in einem Nachrichtenkatalog nach. Es führt zuerst alle Erweiterungen mit doppelten Anführungszeichen aus. Wenn der String nicht in der Übersetzungsdatenbank gefunden wird, wird er als eigene Übersetzung verwendet. Die eingebaute Annahme ist, dass die Zeichenfolgen in Englisch sind.
Sie möchten diese wahrscheinlich nicht verwenden, aber wenn Sie sie sehen, können Sie sie im Allgemeinen als reguläre Anführungszeichen behandeln.
Bemerkenswert ist, dass es keine Art von Anführungszeichen gibt, die sowohl die Erweiterung eingebetteter Parameter als auch das Entweichen eingebetteter Zeichen ermöglichen. In den meisten Fällen, in denen Sie dies wünschen, sind Sie besser dran (sicherer), wenn Sie Folgendes verwenden
printf
:Dies trennt klar, welche Teile einem Zeichenverlust unterliegen und welche Datenwerte.
Ein weiterer Grund ist, dass alle diese Anführungszeichen ein einzelnes "Wort" in der Shell erzeugen, es sei denn , in Anführungszeichen wird
$@
eine Array-Erweiterung${x[@]}
verwendet. Beide Formen mit einem Anführungszeichen sind immer ein Wort und werden nie weiter erweitert.quelle
$"..."
ist auch von ksh93 und wurde zu bash in 2.0 hinzugefügt.\cX
inzsh
. Es ist\CX
oder\C-X
dort (hat\c
bereits eine besondere Bedeutung inecho
)'let x="'$PATH\"
ist falsch in Listenkontexten in anderen Shells alszsh
as,$PATH
die nicht in Anführungszeichen gesetzt sind (wäre also split + glob unterworfen, was Sie hier nicht möchten).