GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Der Unterschied zwischen den Anführungszeichen „…“, „…“, $“…“ und „$“…“ in der Shell?

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 wie n 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
Verwandte:Dhcpv6 – zustandsbehaftet VS zustandslos, was ist der Unterschied zwischen ihnen?

$’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 nnn
  • xHH , ein einzelnes Byte mit dem Hexadezimalwert HH
  • uHHHH , der Unicode-Codepunkt, dessen hexadezimaler Index HHHH ist
  • UHHHHHHHH , 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.


Linux
  1. Der genaue Unterschied zwischen einem „Terminal“, einer „Shell“, einem „tty“ und einer „Konsole“?

  2. Unterschied zwischen Login-Shell und Nicht-Login-Shell?

  3. Der Unterschied in der Verwendung zwischen Shell-Variablen und Umgebungsvariablen?

  4. Was ist der Unterschied zwischen Sudo Su – und Sudo Su –?

  5. Der Unterschied zwischen Getty und Agetty?

Was ist der Unterschied zwischen Linux und Unix?

Was ist der Unterschied zwischen Login- und Non-Login-Shell

Was ist der Unterschied zwischen einer Konsole, einem Terminal und einer Shell?

Was ist der Unterschied zwischen nohup und kaufmännischem Und?

Unterschied zwischen '{}' und {} im Find-Befehl?

Was ist der Unterschied zwischen ls und l?