Wie verwende ich ein Sonderzeichen als normales?

13

Viele Fragen wie "Wie schreibe ich das doppelte Anführungszeichen (")? " werden gefragt, und wir möchten unsere Community nicht mit derselben Antwort überhäufen (Geben Sie sie ein, als \"ob sie nicht in 's "eingeschlossen wäre , wenn sie in 's eingeschlossen wäre.) Die Frage ist also hier.

Sie können keine Sonderzeichen in ein Terminal eingeben, wie normale Zeichen. Dieser Befehl schlägt beispielsweise fehl:

echo Updates (11)

Wie kann man diese Zeichen im Terminal so eingeben, als wären sie normale Zeichen?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>
EKons
quelle
Es gibt keine Unix-Shell, von der ich weiß, wo Carriage Return etwas Besonderes ist. =, @Und %in einigen Muscheln in einigen Kontexten sind etwas Besonderes.
Stéphane Chazelas
@ StéphaneChazelas Umm ... carriage return ( ^M) verhält sich ^Jfür mich wie line feed ( ) (Ubuntu 14.04, sh).
EKons
Nein, Ihre Terminal - Treiber - Transformationen ^Mzu ^Jauf Eingabe aber ^Mnicht besondere an die Schale und nicht zitiert müssen. Geben echo ^V^M | hdSie ein und Sie sehen das Zeichen 0d (und die durch Echo angehängte 0a).
Stéphane Chazelas
@ StéphaneChazelas Umm ... Ich weiß nicht was es hdist, vielleicht xxdist es besser als Hex Viewer.
EKons
Welcher auch immer. Verwenden Sie POSIX od -tx1oder sed -n lvims xxd, wenn Sie nicht haben hd. Einige Systeme haben auch cat -vteodercat -A
Stéphane Chazelas

Antworten:

26

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 Sonderzeichen sind. Zum Beispiel ist in den meisten Shells *und ?nur in Listenkontexten, in POSIX- oder csh-ähnlichen Shells, ~nur am Anfang eines Wortes oder nach bestimmten Zeichen wie etwas Besonderes :. Gleiches gilt für =in zsh. In einigen Shells [ist es nur dann etwas Besonderes, wenn es (mit gewissen Einschränkungen) von einem ].

In einigen Shells wie bashoder yashvariieren Sonderzeichen wie Leerzeichenbegrenzer ebenfalls mit dem Gebietsschema.

Die Anführungszeichen (um die spezielle Bedeutung dieser Zeichen zu entfernen) variieren ebenfalls stark zwischen den einzelnen Shells.

Borowski-ähnliche Muscheln

Eine Zusammenfassung für Bourne-ähnliche Shells (das sind die Shells, von denen bekannt ist, dass sie shauf dem einen oder anderen System seit den 80er Jahren aufgerufen werden ):

Borowski-Schale

Spezielle Charaktere:

  • "\'&|;()^`<>$, Leerzeichen, Zeilenvorschub und Tabulator sind in einfachen Befehlszeilen etwas Besonderes, wenn sie nicht in Anführungszeichen stehen.
  • #(außer in der frühen Version) steht speziell am Anfang einer Zeile oder nach einem nicht zitierten Leerzeichen, Tabulator oder &|()^<>;`.
  • {und }sind nur insofern besonders, als es sich um Shell-Schlüsselwörter handelt (also nur Wörter in Befehlsposition).
  • *?[sind speziell als Globbing-Operatoren, also nur in Listenkontexten. Im Fall von [handelt es sich [...]entweder um den Globbing-Operator, [oder er muss ]nur in Anführungszeichen gesetzt werden, um die spezielle 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 nach set -k).

Betreiber zitieren

  • \setzt alle Sonderzeichen mit Ausnahme von Zeilenumbrüchen in Anführungszeichen (dies \<newline>ist eine Möglichkeit, eine lange logische Zeile in die nächste physische Zeile fortzusetzen , sodass die Sequenz entfernt wird). Beachten Sie, dass Backticks zusätzliche Komplexität hinzufügen, da sie \zuerst verwendet werden, um das schließende Backtick zu umgehen und dem Parser zu helfen. Innerhalb von doppelten Anführungszeichen \darf nur verwendet werden, um sich selbst zu entziehen ", $und `( \<newline>ist weiterhin eine Zeilenfortsetzung). Innerhalb eines Here-Dokuments, abgesehen von ". \Dies ist die einzige Möglichkeit, Zeichen in Dokumenten zu entkommen.
  • "..."doppelte Anführungszeichen umgehen alle Zeichen außer sich selbst \, $und `.
  • '...' einfache Anführungszeichen entziehen sich allen Zeichen außer sich selbst.

POSIX-Schalen

POSIX-Shells verhalten sich hauptsächlich wie die Bourne-Shell, außer dass:

ksh

wie POSIX, nur dass:

  • {string}ist besonders, wenn der String ein nicht zitiertes enthält ,(oder ..in einigen Fällen und bei einigen Versionen).
  • ksh93 hat einen zusätzlichen speziellen Anführungszeichenoperator: $'...'mit komplexen Regeln. Das Operator wird auch (mit einigen Variationen) gefunden bash, zsh, mkshund FreeBSD und Busybox sh.
  • ksh93$"..."Hat auch einen Anführungszeichenoperator, der funktioniert, "..."außer dass die Zeichenfolge der Lokalisierung unterliegt (kann so konfiguriert werden, dass sie in die Sprache des Benutzers übersetzt wird). mkshignoriert den $in $"...".

bash

wie ksh93aber:

  • In Gebietsschemata für Einzelbytezeichen werden alle Leerzeichen (entsprechend dem Gebietsschema) als Trennzeichen (wie Leerzeichen oder Tabulatoren) betrachtet. Tatsächlich bedeutet dies, dass Sie alle Bytes mit dem achten gesetzten Bit in Anführungszeichen setzen sollten, falls sie in einem Gebietsschema ein Leerzeichen sein könnten.
  • Wenn die Erweiterung des csh-Verlaufs wie in interaktiven Instanzen aktiviert ist, !ist dies in einigen Kontexten besonders und doppelte Anführungszeichen werden nicht immer ausgeblendet. Und ^ist besonders zu Beginn eines Befehls.

zsh

wie ksh93aber:

  • Gleiche Anmerkung wie für die bashErweiterung der csh-Historie
  • =ist etwas Besonderes als erstes Zeichen eines Wortes ( =lserweitert auf /bin/ls).
  • {und }kann auch Befehlsgruppen öffnen und schließen, wenn sie nicht abgegrenzt sind (wie bei {echo text}Bourne { echo text;}).
  • Ausgenommen für sich [alleine, [muss zitiert werden, auch wenn nicht mit einem abgeschlossen ].
  • Wenn die extendedglobOption aktiviert ist #, werden ^und ~globale Operatoren.
  • Mit der bracecclOption {non-empty-string}ist etwas Besonderes.
  • $"..." wird nicht unterstützt.
  • als besondere Eigenheit, ?ist nicht besonders, wenn Sie einem %(auch zitierten oder erweiterten) Wort am Anfang folgen (um die %?nameAuftragsspezifikation zu ermöglichen )
  • Eine rcquotesOption (standardmäßig nicht aktiviert) ermöglicht die Eingabe von einfachen Anführungszeichen ''in einfachen Anführungszeichen à la rc(siehe unten).

yash

wie POSIXaußer dass.

  • Alle Leerzeichen gelten als Trennzeichen.
  • Mit dieser brace-expandOption wird die Erweiterung der zsh-Stil-Klammer implementiert.

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 [[...]]ksh und ein paar andere Shells, POSIX $((...)), caseKonstrukte ...

Beachten Sie auch, dass das Zitieren andere Nebenwirkungen haben kann, wenn es zu Erweiterungen (mit doppelten Anführungszeichen) kommt oder wenn es auf Dokumenttrennzeichen angewendet wird. Es deaktiviert auch reservierte Wörter und wirkt sich auf die Alias-Erweiterung aus.

Zusammenfassung

In Bourne-ähnlichen Shells !#$^&*?[(){}<>~;'"`\|=sind oder können SPC, TAB, NEWLINE und einige Bytes mit gesetztem 8. Bit (zumindest in bestimmten Kontexten) speziell sein.

Um die spezielle Bedeutung zu entfernen, damit sie buchstäblich behandelt wird, verwenden Sie Anführungszeichen.

Verwenden:

  • '...' So entfernen Sie die spezielle Bedeutung jedes Zeichens:

    printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
  • \ um die spezielle Bedeutung nur eines Zeichens zu entfernen:

    printf '<%s>\n' foo bar\ baz #comment

    Oben wird nur das mit einem vorangestellte Leerzeichen \wörtlich an übergeben printf. Die anderen werden von der Shell als Token-Begrenzer behandelt.

  • verwenden "..."Zeichen zu zitieren , während immer noch Parameter Expansion ermöglicht ( $var, $#, ${foo#bar}...), arithmetische Erweiterung ( $((1+1))auch $[1+1]in einigen Muscheln) und Kommandosubstitution ( $(...)oder die alten Form `...`. Eigentlich die meiste Zeit, haben Sie wollen , dass diese Erweiterungen innerhalb setzen in jedem Fall doppelte Anführungszeichen : Sie können \innerhalb "..."von Anführungszeichen verwenden , um die spezielle Bedeutung der noch speziellen Zeichen (aber nur der Zeichen) zu entfernen.
  • Wenn die Zeichenfolge 'Zeichen enthält , können Sie sie '...'für den Rest weiterhin verwenden und andere Anführungszeichen verwenden, die 'wie "'"oder \'oder ( sofern verfügbar) zitieren können $'\'':

    echo 'This is "tricky", isn'\''t it?'
  • Verwenden Sie die moderne $(...)Form der Befehlsersetzung. Verwenden Sie das alte nur `...`aus Kompatibilitätsgründen mit der Bourne-Shell, dh mit einem sehr alten System, und nur in Variablenzuweisungen, wie in nicht verwenden:

    echo "`echo "foo bar"`"

    Was mit der Bourne-Shell oder den AT & T-Versionen von ksh nicht funktioniert. Oder:

    echo "`echo \"foo bar\"`"

    Was mit Bourne und AT & T ksh funktioniert, aber nicht mit yash, sondern mit:

    var=`echo "foo bar"`; echo "$var"

    das wird mit allen funktionieren.

    Es ist auch unmöglich, sie portabel in doppelte Anführungszeichen zu setzen. Verwenden Sie also wieder Variablen. Beachten Sie auch die spezielle Backslash-Verarbeitung:

    var=`printf '%s\n' '\\'`

    Speichert nur einen Backslash in Backticks $var, da es eine zusätzliche Ebene der Backslash-Verarbeitung gibt (für \, `und $(und auch, "wenn es nicht in Anführungszeichen steht yash)), sodass Sie auch einen benötigen

    var=`printf '%s\n' '\\\\'`

    oder

    var=`printf '%s\n' '\\\'

    stattdessen.

Csh Familie

csh und tcsh haben eine deutlich unterschiedliche Syntax, obwohl die Bourne-Shell noch viele Gemeinsamkeiten aufweist, da sie ein gemeinsames Erbe haben.

Spezielle Charaktere:

  • "\'&|;()^`<>$, Leerzeichen, Zeilenvorschub und Tabulator sind überall etwas Besonderes, wenn sie nicht in Anführungszeichen stehen.
  • #(csh ist die Shell, die #als Kommentar-Leader eingeführt wurde) steht am Anfang eines Skripts oder nach einem nicht zitierten Leerzeichen, Tabulator oder einer neuen Zeile.
  • *?[ sind als Globbing-Operatoren also in Listenkontexten besonders
  • {non-empty-string} ist etwas Besonderes (csh ist die Shell, die die Klammererweiterung eingeführt hat).
  • !und ^sind speziell als Teil der Geschichtserweiterung (wieder eine Erfindung von csh), und Zitierregeln sind speziell.
  • ~ (Tilde-Erweiterung auch eine csh-Erfindung) ist in manchen Zusammenhängen etwas Besonderes.

Betreiber zitieren

Sie sind die gleichen wie für die Bourne-Shell, aber das Verhalten unterscheidet sich. tcsh verhält sich aus der Sicht der Syntax wie csh. Sie werden feststellen, dass viele Versionen von csh böse Fehler aufweisen. Holen Sie sich die neueste Version von tcsh, um eine grob funktionierende Version von csh zu erhalten.

  • \maskiert ein einzelnes Zeichen mit Ausnahme von Newline (wie bei der Bourne-Shell). Es ist der einzige Zitatoperator, der entkommen kann !. \<newline>Es wird nicht entkommen, sondern von einem Befehlstrennzeichen in ein Tokentrennzeichen (wie Leerzeichen) umgewandelt.
  • "..."entkommt alle Zeichen außer sich selbst, $, `, Newline und !. Im Gegensatz zu dem Bourne - Shell, können Sie nicht \entkommen $und nach `innen "...", aber Sie verwenden können , \fliehen !oder Newline (selbst aber nicht , außer wenn vor einem !oder Newline). Ein Literal !ist "\!"und ein Literal \!ist "\\!".
  • '...' Es werden alle Zeichen außer sich selbst !und die Zeilenumbrüche ausgeblendet. Wie für doppelte Anführungszeichen !und Zeilenumbrüche kann mit Backslash maskiert werden.
  • Die Befehlssubstitution erfolgt nur über die `...`Syntax und kann kaum zuverlässig verwendet werden.
  • Variablensubstitution ist auch ziemlich schlecht gestaltet und fehleranfällig. Ein $var:qOperator hilft dabei, zuverlässigeren Code mit Variablen zu schreiben.

Zusammenfassung

Halte dich von csh fern, wenn du kannst. Wenn Sie nicht verwenden können:

  • einfache Anführungszeichen, um die meisten Zeichen in Anführungszeichen zu setzen. !und newline brauchen noch einen \.
  • \ kann die meisten Zeichen entkommen
  • "..."kann einige Erweiterungen zulassen, aber das ist ziemlich fehlerhaft, wenn sie Zeilenumbrüche und / oder Backslash-Zeichen enthalten. Verwenden Sie am besten nur einfache Anführungszeichen und $var:qfür variable Erweiterungen. Sie müssen Schleifen verwenden, wenn Sie Elemente eines Arrays zuverlässig verbinden möchten.

rc Familie

rcist die plan9Shell und wie ihre Nachkommen esund akangawurde auf Unix und Unix-Likes portiert. Dies ist eine Shell mit einer viel saubereren und besseren Syntax, die jeder verwenden würde, wenn wir nicht aus Gründen der Abwärtskompatibilität auf Bourne-ähnliche Shells angewiesen wären.

rc/akanga

Spezielle Charaktere

  • #;&|^$=`'{}()<>, SPC, TAB und NEWLINE sind immer etwas Besonderes, wenn sie nicht in Anführungszeichen stehen.
  • *?[ sind globale Operatoren.

Zitierender Operator

'...'ist der einzige Quotierungsoperator. Ein Wurf 'wird ''in einfachen Anführungszeichen wie folgt geschrieben :

 echo 'it''s so simple isn''t it?'

es

eskönnte als experimentelle Hülle gesehen werden, die auf rc.

Es gibt jedoch einige Unterschiede. Das Interessante an diesem Q / A ist, dass \es sich auch um einen Anführungszeichenoperator handelt (der alle Sonderzeichen mit Ausnahme von Zeilenumbrüchen in Anführungszeichen setzt) ​​und auch verwendet werden kann, um Escape-Sequenzen \neinzuführen, wie z. B. für Zeilenumbrüche, \bfür Backslash ...

Fisch

fish ist ein relativer Neuling (circa 2005), hauptsächlich für den interaktiven Gebrauch gedacht und hat eine deutlich andere Syntax als andere Shells.

spezielle Charaktere

  • "'\()$%{}^<>;&|Immer etwas Besonderes, wenn nicht angegeben (beachten Sie, dass %(für die PID-Erweiterung) ein signifikanter Unterschied zu anderen Schalen besteht und `nichts Besonderes ist).
  • # (Kommentar) speziell, wenn Sie Leerzeichen, Tabulatoren, Zeilenumbrüche oder ;&|^<>
  • *?(aber nicht [...]) Globbing-Operatoren

Betreiber zitieren

  • \zitiert ein einzelnes Sonderzeichen mit Ausnahme von Zeilenumbrüchen, aber beachten Sie, dass es auch als C-Escape-Sequenz ( \n, \b...) -Einführungszeichen fungiert . IOW, \nist kein Anführungszeichen, nsondern ein Zeilenumbruch.
  • "..."zitiert alles außer sich selbst, $und Backslash und Backslash können verwendet werden, um diesen zu entgehen. \<newline>ist eine Linienfortsetzung (entfernt) im Inneren "...".
  • '...'zitiert alles außer sich selbst und \, und Sie können Backslash verwenden, um diese zu entkommen.
Stéphane Chazelas
quelle
Ich habe nur diejenigen aufgenommen, die in allen Kontexten speziell sind (so dass es cdas Gleiche ist \c, cnicht c: command not foundauf STDERR usw. ausgegeben wird). Ich spreche shhier von. Denken Sie auch daran, dass dies eine "Bereinigungs" -Frage ist, dh, sie soll alle diese Zeichen abdecken, sodass nicht mehr als 19 Fragen gestellt werden müssen. Die Frage wurde aufgrund eines Vorfalls gestellt, bei dem für verschiedene Charaktere unterschiedliche Fragen gestellt wurden. Wir möchten hier aufräumen!
EKons
Naja, ?[sind Globbing-Operatoren, sind aber nicht in allen Zusammenhängen speziell, sondern *scheinen es zu sein, weil der Inhalt des aktuellen Verzeichnisses echo *schlecht ist echo(nichts entgeht). echo ?Echo ein Literal ?und echo [Echo ein Literal [. Auch ]ist ein Globbing Oberator zu.
EKons
1
@ ΈρικΚωνσταντόπουλος, *wenn ein Globus auf alle nicht ausgeblendeten Dateien, ?auf nicht ausgeblendete Dateien [a-z]mit einem einzelnen Zeichen und auf Dateien mit einem einzelnen Zeichen zwischen a und z usw. erweitert wird. Wenn sie keiner Datei entsprechen (wie in Ihrem Fall für ?), wird abhängig von der Shell ein No-Match-Fehler angezeigt oder das Muster wird zu sich selbst erweitert. In jedem Fall, auch bei Shell , wo sie sich erweitern, müssen sie zitiert , falls sie kann eine Datei übereinstimmen.
Stéphane Chazelas
Aber, nicht als Globus, *expandiert immer noch zu etwas.
EKons
@ ΈρικΚωνσταντόπουλος, *ist wie ?, wenn es nicht übereinstimmt (für den Fall von *allein, wenn es nur versteckte Dateien im aktuellen Verzeichnis gibt, für a*das es keine Datei gibt, deren Name mit a... beginnt ), es wird entweder zu erweitert selbst ( die meisten Bourne-wie Muscheln) oder wirft eine no-Match - Fehler ( csh, tcsh, fish(Warnung), zsh, bash -O failglob, am frühen Unix - Shells), (oder dehnt sich so gut wie nichts mit der nullglob Option einiger Schalen oder wenn es ein anderes Muster ist das eRWEITERT etwas in csh, tcsh, zsh -o cshnullglob, frühen Unix-Shells).
Stéphane Chazelas
4

1. Flucht

Escape all diese Zeichen mit einem \, wie folgt (funktioniert nicht auf Zeilenumbrüchen / Wagenrücklauf):

$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.

2. Doppelte Anführungszeichen

Fügen Sie den gesamten Text in "s ein, wie folgt :

$ var=variables;echo "Enclose text in \"s. You can also use $var in them. `echo Surprise!!!`"
Enclose text in "s. You can also use variables in them. Surprise!!!

3. Ein Anführungszeichen

Entspricht dem doppelten Anführungszeichen, es gibt jedoch kein spezielles Token.

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof
EKons
quelle
1
Sie beschreiben das Verhalten der fishShell, nicht der Bourne-ähnlichen Shells, bei denen das einfache Anführungszeichen jedes Zeichen in Anführungszeichen setzt (Backslash ist kein Sonderzeichen '...'). Beachten Sie, dass in fish, %ist auch ein Sonderzeichen.
Stéphane Chazelas
@ StéphaneChazelas weiß ich nicht , wie fishfunktioniert, aber meine Erfahrung ist , dass in sh, echo '\\'Echos \ und echo '\''Echos '.
EKons
1
echo '\\'gibt \ aus, weil Sie echoANSI C-Escape-Sequenzen erweitern (einige echoImplementierungen benötigen dies echo -e '\\'). printf '%s\n' '\\'Ausgänge \\.
Stéphane Chazelas
Beachten Sie, dass sheine bestimmte Shell nicht identifiziert wird. Es wurden und werden viele verschiedene und häufig inkompatible Shells genannt sh.
Stéphane Chazelas
@ StéphaneChazelas Oh okay, das werde ich jetzt ändern. Befindet sich \'ein spezielles Token in einer Zeichenfolge in Anführungszeichen?
EKons