Manchmal sehe ich, dass Shell-Skripte all diese verschiedenen Arten verwenden, um einen 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?
Akzeptierte Antwort:
All dies bedeutet etwas anderes, und Sie können verschiedene Dinge hineinschreiben (oder dieselben Dinge mit unterschiedlicher Bedeutung). Verschiedene Arten von Anführungszeichen interpretieren unterschiedliche Escape-Sequenzen in ihnen (something
) oder Variableninterpolationen zulassen oder nicht zulassen ($something
) und andere Arten von Erweiterungen darin.
Kurz:
'...'
ist völlig wörtlich."..."
erlaubt sowohl Variablen als auch eingebettete Anführungszeichen.$'...'
führt Zeichenfluchten wien
durch , erweitert aber keine Variablen.$"..."
ist für menschensprachliche Übersetzungen in Bash und ksh.
‘Einfache Anführungszeichen’
Alles, was Sie zwischen einfache Anführungszeichen schreiben, wird wörtlich behandelt und überhaupt nicht verarbeitet. Backslashes und Dollarzeichen haben dort keine besondere Bedeutung. Das bedeutet, dass Sie ein Zeichen (einschließlich anderer einfacher Anführungszeichen!) nicht mit einem Backslash maskieren, eine Variable interpolieren oder andere Shell-Funktionen verwenden können.
Alle diese Beispiele führen buchstäblich zu dem, was zwischen den Anführungszeichen steht:
Code | Ergebnis |
---|---|
'hello world' | Hallo Welt |
'/pkg/bin:$PATH' | /pkg/bin:$PATH |
'hellonworld' | hellonworld |
'`echo abc`' | `echo abc` |
'I'dn't've' | Keine Ahnung |
Letzteres ist kompliziert – es gibt zwei Zeichenfolgen in einfachen Anführungszeichen werden zusammen mit Text ohne Anführungszeichen ausgeführt. Der erste enthält I
. Der Text ohne Anführungszeichen dn't
enthält ein einfaches Anführungszeichen, das auf Shell-Ebene maskiert wird , also beginnt es nicht mit einer Zeichenfolge in Anführungszeichen und wird als Literalzeichen eingefügt (also dn't
). Die letzte Zeichenfolge in Anführungszeichen ist nur ve
. All diese 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 ist, sie so zusammenzuführen:
'let x="'$PATH"
ergibt
let x="/usr/bin:/bin"
als einzelnes Wort (besser $PATH
in doppelte Anführungszeichen setzen für alle Fälle auch – Leerzeichen oder Globbing-Zeichen in der Variablen Wert kann anders verarbeitet werden – habe ich aber wegen eines lesbaren Laufbeispiels nicht).
„Doppelte Anführungszeichen“
Innerhalb doppelter Anführungszeichen werden zwei Arten von Erweiterungen verarbeitet, und Sie können einen umgekehrten Schrägstrich verwenden, um Zeichen mit Escapezeichen zu versehen, um zu verhindern, dass Erweiterungen oder Escapezeichen verarbeitet werden.
Es gibt zwei Arten von Erweiterungen, die in doppelten Anführungszeichen vorkommen:
- Die mit
$
beginnen (Parametererweiterung$abc
und${abc}
, Befehlsersetzung$(...)
, und arithmetische Erweiterung$((...))
); - Befehlsersetzung durch Backquotes
`abc`
;
Innerhalb der Anführungszeichen kann ein umgekehrter Schrägstrich diese Erweiterungen verhindern, indem er vor $
gesetzt wird oder `
. Es kann auch ein schließendes doppeltes Anführungszeichen maskieren, also "
enthält nur "
in Ihrer Zeichenfolge oder einen anderen umgekehrten Schrägstrich. Alle anderen umgekehrten Schrägstriche werden wörtlich beibehalten – es gibt keine Escapezeichen, um andere Zeichen zu erzeugen, und sie werden nicht entfernt.
Einige dieser Beispiele verhalten sich anders als zuvor, andere nicht:
Code | Ergebnis |
---|---|
"hello world" | Hallo Welt |
"/pkg/bin:$PATH" | /pkg/bin:/bin:/usr/bin |
"hellonworld" | hellonworld |
"hello\nworld" | hellonworld |
"`echo abc`" | abc |
"I'dn't've" | Hätte ich nicht |
"I'dn't've" | Hätte ich nicht |
"I"dn"t've" | Habe ich nicht |
$’ANSI-C quoting’
Diese Art des Zitierens erlaubt die Verarbeitung von Backslash-Escapes im C-Stil, aber nicht eingebettete Variablen oder Substitutionen. Es ist das einzige Art von Zitaten, die Escapezeichen unterstützen .
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 kann es kostenlos.
Alle diese Escapes können mit ihren C-Bedeutungen verwendet werden:a
, b
, f
, n
, r
, t
, v
, und das Literal maskiert \
, '
, "
, und ?
. Sie unterstützen auch die Erweiterungen e
(Escape-Zeichen) und in Bash und ksh cx
(was mit Strg-x eingegeben werden würde, z.B. cM
ist Wagenrücklauf). Shells haben eine Reihe kleinerer eigener Erweiterungen.
Es erlaubt auch vier Arten von generischen Escapezeichen:
nnn
, ein einzelnes Byte mit Oktalwert nnnxHH
, ein einzelnes Byte mit dem Hexadezimalwert HHuHHHH
, der Unicode-Codepunkt, dessen hexadezimaler Index HHHH istUHHHHHHHH
, der Unicode-Codepunkt, dessen hexadezimaler Index HHHHHHHH ist
Alle diese Ziffern sind nach der ersten optional.
$
und `
haben keine Bedeutung und werden wörtlich beibehalten, sodass Sie dort keine Variable einfügen können.
Code | Ergebnis |
---|---|
$'hello world' | Hallo Welt |
$'/pkg/bin:$PATH' | /pkg/bin:$PATH |
$'hellonworld' | Hallo Welt |
$'`echo abc`' | `echo abc` |
$'I'dn't've' | Hätte ich nicht |
$'U1f574u263A' | 🕴☺ |
Die meisten dieser Escapes können Sie mit printf
simulieren Befehl, obwohl POSIX nur \
erfordert , a
, b
, f
, n
, r
, t
, v
, und nnn
dort zu arbeiten. Sie können die Befehlsersetzung verwenden, um ein printf
einzubetten in doppelte Anführungszeichen, falls erforderlich:"Path:$(printf 't')$PATH"
.
$”Lokale Übersetzung”
Dies ist eine ksh- und Bash-spezifische Erweiterung zum Lokalisieren von Textzeichenfolgen in natürlicher Sprache und sucht den Teil innerhalb der Anführungszeichen in einem Nachrichtenkatalog. Es führt zuerst alle doppelten Anführungszeichen-Erweiterungen aus. Wenn die Zeichenfolge nicht in der Übersetzungsdatenbank gefunden wird, wird sie als eigene Übersetzung verwendet. Die eingebaute Annahme ist, dass die Zeichenfolgen in Englisch sind.
Sie möchten dieses wahrscheinlich nicht verwenden, aber wenn Sie es sehen, können Sie es im Allgemeinen als normale doppelte Anführungszeichen behandeln.
Eine Anmerkung ist, dass es nein gibt Art des Zitierens, das sowohl eingebettete Parametererweiterungen als auch eingebettete Zeichen-Escapes ermöglicht. In den meisten Fällen, in denen Sie dies wünschen würden, wäre es besser (sicherer), printf
zu verwenden :
printf 'New path: e[1m%se[0m' "/pkg/bin:$PATH:"
Dadurch wird klar getrennt, welche Teile Zeichen-Escapezeichen unterliegen und welche Datenwerte sind.
Ein weiterer Grund ist, dass all diese Zitierstile ein einziges „Wort“ in der Shell erzeugen, es sei denn [email protected]
oder eine Array-Erweiterung ${x[@]}
wird in doppelten Anführungszeichen verwendet. Beide einfachen Anführungszeichen sind immer ein Wort und werden nie weiter erweitert.