Viele Fragen wie „Wie tippe ich das doppelte Anführungszeichen (“) ein?“ werden gestellt, und wir möchten unsere Community nicht mit der gleichen Antwort überhäufen (Geben Sie es als "
ein falls nicht eingeschlossen in '
s, "
falls eingeschlossen in '
s.) Die Frage ist also hier.
Sie können Sonderzeichen nicht wie normale Zeichen in ein Terminal eingeben, z. dieser Befehl schlägt fehl:
echo Updates (11)
Also, wie kann man diese Zeichen in das Terminal eingeben, als wären sie normale?
!#$^&*?[](){}<>~;'"|<space><tab><newline>
Akzeptierte Antwort:
Das hängt sehr von der Schale ab. Einzelheiten finden Sie in Ihrem Shell-Handbuch.
Beachten Sie auch, dass einige Zeichen nur in bestimmten Kontexten etwas Besonderes sind. In den meisten Shells zum Beispiel *
und ?
sind nur speziell in Listenkontexten,
in POSIX oder csh-ähnlichen Shells, ~
ist nur am Anfang eines Wortes oder nach einigen Zeichen wie :
etwas Besonderes . Gleiches gilt für =
in zsh
. In einigen Shells ist [
ist nur etwas Besonderes, wenn es (mit einigen Einschränkungen) mit einem ]
übereinstimmt .
In einigen Shells wie bash
oder yash
, Sonderzeichen wie leere Token-Trennzeichen variieren ebenfalls je nach Gebietsschema.
Die Zitieroperatoren (um die besondere Bedeutung dieser Zeichen zu entfernen) variieren ebenfalls stark zwischen den Shells.
Bourne-ähnliche Muscheln
Eine Zusammenfassung für Bourne-ähnliche Shells (das sind die Shells, die bekanntermaßen sh
genannt werden auf irgendeinem System seit den 80ern):
Bourne-Shell
Sonderzeichen:
"'&|;()^`<>$
, Leerzeichen, Zeilenumbrüche und Tabulatoren sind in einfachen Befehlszeilen etwas Besonderes, wenn sie nicht in Anführungszeichen gesetzt werden.#
(außer in früheren Versionen) ist am Anfang einer Zeile oder nach einem Leerzeichen ohne Anführungszeichen, einem Tabulator oder&|()^<>;`
etwas Besonderes .{
und}
sind nur darin besonders, dass sie Shell-Schlüsselwörter sind (also nur Wörter in Kommandoposition).*?[
sind speziell als Globbing-Operatoren, also nur in Listenkontexten. Im Fall von[
, es ist[...]
das ist der Globbing-Operator, entweder[
oder]
müssen nur zitiert werden, um die besondere Bedeutung zu entfernen.=
ist besonders in Kontexten, in denen es als Zuweisungsoperator behandelt wird. Das heißt, in einem einfachen Befehl für alle Wörter, die keinem Argument folgen (außer nachset -k
).
Operatoren zitieren
setzt alle Sonderzeichen außer Newline in Anführungszeichen (
<newline>
ist eine Möglichkeit, eine lange logische fortzusetzen Linie auf die nächste physische Zeile, sodass die Sequenz entfernt wird). Beachten Sie, dass Backticks zusätzliche Komplexität hinzufügen, dawird zuerst verwendet, um dem schließenden Backtick zu entkommen und dem Parser zu helfen. Innerhalb doppelter Anführungszeichen,
darf nur verwendet werden, um sich selbst zu maskieren,
"
,$
und`
(<newline>
ist immer noch eine Zeilenfortsetzung). Innerhalb eines Here-Dokuments dasselbe, außer für"
.ist die einzige Möglichkeit, Zeichen in diesen Dokumenten zu maskieren.
"..."
doppelte Anführungszeichen maskieren alle Zeichen außer sich selbst,,
$
und`
.'...'
einfache Anführungszeichen maskieren alle Zeichen außer sich selbst.
POSIX-Shells
POSIX-Shells verhalten sich größtenteils wie die Bourne-Shell, außer dass:
^
ist kein Sonderzeichen mehr~
ist in manchen Kontexten etwas Besonderes{
darf etwas Besonderes sein und sollte daher zitiert werden.
ksh
wie POSIX, außer dass:
{string}
ist etwas Besonderes, wenn der String einen nicht in Anführungszeichen gesetzten,
enthält (oder..
in einigen Fällen und mit einigen Versionen).- ksh93 hat einen zusätzlichen speziellen Anführungszeichen-Operator:
$'...'
mit komplexen Regeln. Dieser Operator findet sich (mit einigen Variationen) auch inbash
,zsh
,mksh
und FreeBSD und busyboxsh
. ksh93
hat auch ein$"..."
Zitieroperator, der wie"..."
funktioniert außer dass die Zeichenfolge der Lokalisierung unterliegt (könnte so konfiguriert werden, dass sie in die Sprache des Benutzers übersetzt wird).mksh
ignoriert das$
in$"..."
.- seit
ksh93r
,ksh93
unterstützt csh-Stil (standardmäßig nicht aktiviert) mit-H
/-o histexpand
in interaktiven Shells), was^
ergibt am Anfang von Befehlen und!
Besondere.!
ist dann in manchen Kontexten etwas Besonderes (nicht, wenn ein Leerzeichen oder TAB folgt, noch in diesen Dokumenten) und wird nicht durch doppelte Anführungszeichen maskiert. Nur Backslash (nicht innerhalb doppelter Anführungszeichen) und einfache Anführungszeichen werden als Escapezeichen verwendet.
bash
wie ksh93
aber:
- in Ein-Byte-Zeichen-Locales alle leer (je nach Gebietsschema) werden Zeichen als Trennzeichen betrachtet (wie Leerzeichen oder Tabulatoren). In der Tat bedeutet das, dass Sie alle Bytes mit gesetztem 8. Bit in Anführungszeichen setzen sollten, falls sie in einigen Gebietsschemas ein Leerzeichen sein könnten.
- Die Erweiterung des csh-Verlaufs ist in interaktiven Instanzen standardmäßig aktiviert, mit den gleichen Hinweisen wie bei ksh93 oben, außer in neueren Versionen von
bash
,!
ist manchmal auch nichts Besonderes, wenn ein"
folgt .
zsh
wie ksh93
aber:
- selbe Anmerkung wie für
bash
für die csh-Verlaufserweiterung =
als erstes Zeichen eines Wortes besonders ist (=ls
erweitert sich zu/bin/ls
).{
und}
kann auch Befehlsgruppen öffnen und schließen, wenn sie nicht getrennt sind (wie in{echo text}
funktioniert wie Bournes{ echo text;}
).- mit Ausnahme von
[
allein,[
muss in Anführungszeichen gesetzt werden, auch wenn es nicht mit einem]
abgeschlossen wird . - Mit dem
extendedglob
Option aktiviert,#
,^
und~
sind Globbing-Operatoren. - Mit dem
braceccl
Option,{non-empty-string}
ist etwas Besonderes. $"..."
wird nicht unterstützt.- als besondere Macke,
?
ist nichts Besonderes, wenn einem%
gefolgt wird (sogar in Anführungszeichen oder erweitert) am Anfang eines Wortes (um den%?name
Stellenbeschreibung) - ein
rcquotes
Option (standardmäßig nicht aktiviert) erlaubt es, einfache Anführungszeichen als''
einzugeben in einfachen Anführungszeichen à larc
(siehe unten).
yash
wie POSIX
außer das.
- Alle Leerzeichen werden als Trennzeichen betrachtet.
- Mit dem
brace-expand
Option, implementiert Klammererweiterung im zsh-Stil.
Für alle Shells gibt es einige spezielle Kontexte, in denen das Zitieren anders funktioniert. Wir haben hier bereits Dokumente und Backticks erwähnt, aber es gibt auch [[...]]
in ksh und einigen anderen Shells POSIX $((...))
, case
Konstrukte…
Beachten Sie auch, dass das Zitieren andere Nebenwirkungen haben kann, wenn es um Erweiterungen (mit doppelten Anführungszeichen) geht oder wenn es auf hier Dokumenttrennzeichen angewendet wird. Es deaktiviert auch reservierte Wörter und wirkt sich auf die Aliaserweiterung aus.
Zusammenfassung
In Bourne-ähnlichen Shells !#$^&*?[(){}<>~;'"`|=
, SPC, TAB, NEWLINE und einige Bytes mit gesetztem 8. Bit sind oder können etwas Besonderes sein (zumindest in einigen Kontexten).
Um die besondere Bedeutung zu entfernen, damit sie wörtlich behandelt werden, verwenden Sie Anführungszeichen.
Verwendung:
-
'...'
um die besondere Bedeutung jedes Zeichens zu entfernen:printf '%sn' '// Those $quoted$ strings are passed literally as single arguments (without the enclosing quotes) to `printf`'
-
um die besondere Bedeutung nur eines Zeichens zu entfernen:
printf '<%s>n' foo bar baz #comment
Oben nur das Leerzeichen mit vorangestelltem
wird wörtlich an
printf
übergeben . Die anderen werden von der Shell als Token-Trennzeichen behandelt. -
Verwenden Sie
"..."
um Zeichen in Anführungszeichen zu setzen, während die Parametererweiterung weiterhin erlaubt ist ($var
,$#
,${foo#bar}
…), arithmetische Erweiterung ($((1+1))
, auch$[1+1]
in einigen Shells) und Befehlsersetzung ($(...)
oder die alte Form`...`
. Tatsächlich möchten Sie diese Erweiterungen meistens sowieso in doppelte Anführungszeichen setzen. Sie könnenverwenden innerhalb von
"..."
um die Sonderbedeutung der Zeichen zu entfernen, die immer noch Sonderzeichen sind (aber nur sie). -
wenn der String
'
enthält Zeichen können Sie immer noch'...'
verwenden für den Rest und verwenden Sie andere Quoting-Mechanismen, die'
zitieren können wie"'"
oder'
oder (wo verfügbar)$'''
:echo 'This is "tricky", isn'''t it?'
-
Verwenden Sie das moderne
$(...)
Form der Befehlsersetzung. Verwenden Sie nur den alten`...`
aus Gründen der Kompatibilität mit der Bourne-Shell, also zu sehr altem System, und nur in Variablenzuweisungen, wie in use:echo "`echo "foo bar"`"
Was mit der Bourne-Shell oder den AT&T-Versionen von ksh nicht funktioniert. Oder:
echo "`echo "foo bar"`"
Das funktioniert mit Bourne und AT&T ksh, aber nicht mit
yash
(Änderung 2020: allerdings nur in Version 2.41 und früher, es wurde seitdem in 2.42 / bug report / commit geändert), aber benutze:var=`echo "foo bar"`; echo "$var"
was mit allen funktioniert.
Es ist auch nicht möglich, sie portabel mit doppelten Anführungszeichen zu verschachteln, also verwenden Sie wieder Variablen. Achten Sie auch auf die spezielle Backslash-Verarbeitung:
var=`printf '%sn' '\'`
Speichert nur einen Backslash innerhalb von
$var
, da es eine zusätzliche Ebene der Backslash-Verarbeitung gibt (für, ` und
$
(und auch"
wenn sie zitiert werden, außer inyash
)) innerhalb von Backticks, also brauchst du entwedervar=`printf '%sn' '\\'`
oder
var=`printf '%sn' '\'
stattdessen.
Csh-Familie
csh und tcsh haben eine deutlich unterschiedliche Syntax, obwohl es immer noch viele Gemeinsamkeiten mit der Bourne-Shell gibt, da sie ein gemeinsames Erbe teilen.
Sonderzeichen:
"'&|;()^`<>$
, Leerzeichen, Zeilenumbrüche und Tabulatoren sind überall etwas Besonderes, wenn sie nicht in Anführungszeichen gesetzt werden.#
(csh ist die Shell, die#
eingeführt hat als Kommentarführer) ist etwas Besonderes am Anfang eines Skripts oder nach einem nicht in Anführungszeichen gesetzten Leerzeichen, Tabulator oder Zeilenumbruch.*?[
sind speziell als Globbing-Operatoren also in Listenkontexten{non-empty-string}
ist etwas Besonderes (csh ist die Shell, die die Klammererweiterung eingeführt hat).!
und^
sind speziell als Teil der History-Erweiterung (wiederum eine csh-Erfindung), und Zitierregeln sind speziell.~
(Tilde-Erweiterung auch eine csh-Erfindung) ist in manchen Kontexten etwas Besonderes.
Operatoren zitieren
Sie sind die gleichen wie bei der Bourne-Shell, aber das Verhalten unterscheidet sich. tcsh sich syntaktisch wie csh verhält, werden Sie feststellen, dass viele Versionen von csh böse Fehler aufweisen. Holen Sie sich die neueste Version von tcsh, um eine ungefähr funktionierende Version von csh zu erhalten.
maskiert ein einzelnes Zeichen außer Newline (wie bei der Bourne-Shell). Es ist der einzige Zitieroperator, der
!
maskieren kann .<newline>
maskiert es nicht, sondern wandelt es von einem Befehlstrenner in einen Token-Trenner um (wie Leerzeichen)"..."
maskiert alle Zeichen außer sich selbst,$
,`
, Zeilenumbruch und!
. Im Gegensatz zur Bourne-Shell können Sienicht verwenden um
$
zu entkommen und`
innerhalb von"..."
, aber Sie könnenverwenden um
!
zu entkommen oder Zeilenumbruch (aber nicht selbst, außer vor einem!
oder Zeilenumbruch). Ein wörtlicher!
ist"!"
und ein wörtliches!
ist"\!"
.'...'
maskiert alle Zeichen außer sich selbst,!
und Zeilenumbruch. Wie für doppelte Anführungszeichen,!
und Zeilenumbrüche können mit Backslash maskiert werden.- Befehlsersetzung geht nur über
`...`
Syntax und kann kaum zuverlässig verwendet werden. - Variablensubstitution ist auch ziemlich schlecht gestaltet und fehleranfällig. Ein
$var:q
-Operator hilft dabei, zuverlässigeren Code mit Variablen zu schreiben.
Zusammenfassung
Halten Sie sich von csh fern, wenn Sie können. Wenn Sie nicht verwenden können:
- einfache Anführungszeichen, um die meisten Zeichen zu zitieren.
!
und Newline benötigen noch einen.
kann den meisten Zeichen entkommen
"..."
kann einige Erweiterungen darin zulassen, aber das ist ziemlich fehlerhaft, wenn sie Newline- und/oder Backslash-Zeichen einbetten, am besten ist es, nur einfache Anführungszeichen und$var:q
zu verwenden für variablen Ausbau. Sie müssen Schleifen verwenden, wenn Sie Elemente eines Arrays zuverlässig verbinden möchten.
rc
Familie
rc
ist der plan9
Shell und wie ihre Nachkommen es
und akanga
wurde auf Unix und Unix-likes portiert. Das ist eine Shell mit einer viel saubereren und besseren Syntax, die jeder verwenden würde, wenn wir aus Gründen der Abwärtskompatibilität nicht auf Bourne-ähnliche Shells angewiesen wären.
rc
/akanga
Sonderzeichen
#;&|^$=`'{}()<>
, SPC, TAB und NEWLINE sind immer etwas Besonderes, wenn sie nicht in Anführungszeichen gesetzt werden.*?[
sind Globbing-Operatoren.
Quotierer
'...'
ist der einzige Quotierungsoperator. Ein wörtlicher '
wird mit ''
geschrieben in einfachen Anführungszeichen wie in:
echo 'it''s so simple isn''t it?'
es
es
könnte als Experiment angesehen werden Shell basierend auf rc
.
Es hat jedoch ein paar Unterschiede. Interessant für diese Frage/Antwort ist ist auch ein Zitieroperator (der alle Sonderzeichen außer Newline zitiert) und kann auch verwendet werden, um Escape-Sequenzen wie
n
einzufügen für Zeilenumbruch b
für Backslash…
Fisch
fish ist ein relativer Newcomer (ca. 2005), ist in erster Linie für den interaktiven Einsatz gedacht und hat auch eine deutlich andere Syntax als andere Shells.
Sonderzeichen
"'()$%{}^<>;&|
immer etwas Besonderes, wenn es nicht in Anführungszeichen steht (beachten Sie den%
(für die PID-Erweiterung) als signifikanten Unterschied zu anderen Shells und`
ist nichts Besonderes)#
(Kommentar) speziell, wenn auf Leerzeichen ohne Anführungszeichen, Tabulatoren, Zeilenumbrüche oder;&|^<>
folgt*?
(aber nicht[...]
) Globbing-Operatoren
Operatoren zitieren
setzt ein einzelnes Sonderzeichen außer Newline in Anführungszeichen, aber Vorsicht, es dient auch als C-Escape-Sequenz (
n
,b
…) Einführer. IOW,n
ist keinn
in Anführungszeichen sondern ein Zeilenumbruch."..."
alles in Anführungszeichen außer sich selbst,$
und Backslash und Backslash können verwendet werden, um diese zu maskieren.<newline>
ist eine Zeilenfortsetzung (entfernt) innerhalb von"..."
.'...'
alles außer sich selbst undin Anführungszeichen setzt , und Sie können den umgekehrten Schrägstrich verwenden, um diese zu maskieren.