Durch das Einschließen von Zeichen in einfache Anführungszeichen ( ') wird der Literalwert jedes Zeichens in den Anführungszeichen beibehalten. Ein einfaches Anführungszeichen darf nicht zwischen einfachen Anführungszeichen stehen, selbst wenn ein Backslash vorangestellt ist.
Zeichen in doppelten Anführungszeichen (umschließende ") bewahrt den wörtlichen Wert aller Zeichen innerhalb der Anführungszeichen, mit Ausnahme von $, `, \, und, wenn die Geschichte Erweiterung aktiviert ist, !. Die Zeichen $und `behalten ihre besondere Bedeutung in doppelten Anführungszeichen (siehe Shell-Erweiterungen ). Der Backslash behält seine besondere Bedeutung nur , wenn sie durch eine der folgenden Zeichen folgen: $, `, ",\oder Newline. In doppelten Anführungszeichen werden Backslashes entfernt, auf die eines dieser Zeichen folgt. Backslashes vor Zeichen ohne besondere Bedeutung bleiben unverändert. Ein doppeltes Anführungszeichen kann in doppelten Anführungszeichen angegeben werden, indem ein Backslash vorangestellt wird. Wenn diese Option aktiviert ist, wird die Verlaufserweiterung ausgeführt, es sei denn, ein !in doppelten Anführungszeichen angegebenes Zeichen wird mit einem Backslash maskiert. Der Backslash vor dem !wird nicht entfernt.
Die speziellen Parameter *und @haben in doppelten Anführungszeichen eine besondere Bedeutung (siehe Shell-Parametererweiterung ).
Was ist, wenn Sie ein git_promptGit verwenden PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ', das von Git bereitgestellt wird ? Sie schlagen vor, es wie folgt zu verwenden. Die Git-Eingabeaufforderung sollte demnach nicht funktionieren. Haben die PS#Variablen etwas Besonderes ? oder warum funktioniert es, wenn es nicht die Interpolation macht.
Ekiim
@ekiim Dieser genaue Text wird (unverändert) in gesetzt PS1. Versuche echo $PS1zu sehen, was ich meine. Wird PS1jedoch vor der Anzeige ausgewertet (siehe PROMPTINGAbschnitt in der Bash-Manpage). Versuchen Sie es, um dies zu testen PS1='$X'. Sie werden keine Eingabeaufforderung haben. Dann laufen X=foound plötzlich ist Ihre Eingabeaufforderung "foo" ( PS1wurde ausgewertet, wenn eingestellt statt angezeigt , hätten Sie immer noch keine Eingabeaufforderung).
Adam Batkin
262
Die akzeptierte Antwort ist großartig. Ich mache eine Tabelle, die zum schnellen Verständnis des Themas beiträgt. Die Erklärung beinhaltet eine einfache Variable asowie ein indiziertes Array arr.
Wenn wir setzen
a=apple # a simple variable
arr=(apple)# an indexed array with a single element
und dann echoden Ausdruck in der zweiten Spalte, würden wir das Ergebnis / Verhalten erhalten, das in der dritten Spalte gezeigt wird. In der vierten Spalte wird das Verhalten erläutert.
# | Expression | Result | Comments
---+-------------+-------------+--------------------------------------------------------------------
1 | "$a" | apple | variables are expanded inside ""
2 | '$a' | $a | variables are not expanded inside ''
3 | "'$a'" | 'apple' | '' has no special meaning inside ""
4 | '"$a"' | "$a" | "" is treated literally inside ''
5 | '\'' | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
6 | "red$arocks"| red | $arocks does not expand $a; use ${a}rocks to preserve $a
7 | "redapple$" | redapple$ | $ followed by no variable name evaluates to $
8 | '\"' | \" | \ has no special meaning inside ''
9 | "\'" | \' | \' is interpreted inside "" but has no significance for '
10 | "\"" | " | \" is interpreted inside ""
11 | "*" | * | glob does not work inside "" or ''
12 | "\t\n" | \t\n | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi` | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]} | array access not possible inside ''
16 | "${arr[0]}" | apple | array access works inside ""
17 | $'$a\'' | $a' | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'" | $'\t' | ANSI-C quoting is not interpreted inside ""
19 | '!cmd' | !cmd | history expansion character '!' is ignored inside ''
20 | "!cmd" | cmd args | expands to the most recent command matching "cmd"
21 | $'!cmd' | !cmd | history expansion character '!' is ignored inside ANSI-C quotes
---+-------------+-------------+--------------------------------------------------------------------
Die akzeptierte Antwort lautet am Ende: The special parameters * and @ have special meaning when in double quotesWie kommt es also zu "*"Ergebnissen *?
Anddero
2
@ Karl-AnderoMere, weil sie in diesem Fall überhaupt nicht als Parameter erweitert werden. "$@"und "$*"sind Parametererweiterungen. "@"und "*"sind nicht.
Charles Duffy
@ CharlesDuffy Danke, es macht jetzt Sinn!
Anddero
3
Nummer 9 echo "\'", gibt mich zurück \'.
MaxGyver
@ MaxGyver: Danke, dass du darauf hingewiesen hast. Ich habe die Antwort aktualisiert.
Codeforester
233
Wenn Sie sich darauf beziehen, was passiert, wenn Sie etwas wiedergeben, geben die einfachen Anführungszeichen buchstäblich wieder, was Sie zwischen ihnen haben, während die doppelten Anführungszeichen Variablen zwischen ihnen auswerten und den Wert der Variablen ausgeben.
Zum Beispiel dies
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
wird dies geben:
double quotes gives you sometext
single quotes gives you $MYVAR
Andere haben es sehr gut erklärt und wollen nur mit einfachen Beispielen geben.
Um Text können einfache Anführungszeichen verwendet werden, um zu verhindern, dass die Shell Sonderzeichen interpretiert. Dollarzeichen, Leerzeichen, kaufmännisches Und, Sternchen und andere Sonderzeichen werden ignoriert, wenn sie in einfache Anführungszeichen gesetzt werden.
$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
Es wird dies geben:
All sorts of things are ignored in single quotes, like $ &*;|.
Das einzige, was nicht in einfache Anführungszeichen gesetzt werden kann, ist ein einfaches Anführungszeichen.
Doppelte Anführungszeichen verhalten sich ähnlich wie einfache Anführungszeichen, außer dass doppelte Anführungszeichen es der Shell weiterhin ermöglichen, Dollarzeichen, hintere Anführungszeichen und umgekehrte Schrägstriche zu interpretieren. Es ist bereits bekannt, dass Backslashes die Interpretation eines einzelnen Sonderzeichens verhindern. Dies kann in doppelten Anführungszeichen hilfreich sein, wenn ein Dollarzeichen anstelle einer Variablen als Text verwendet werden muss. Außerdem können doppelte Anführungszeichen maskiert werden, damit sie nicht als Ende einer Zeichenfolge in Anführungszeichen interpretiert werden.
$ echo "Here's how we can use single ' and double \" quotes within double quotes"
Es wird dies geben:
Here's how we can use single ' and double " quotes within double quotes
Es kann auch bemerkt werden, dass das Apostroph, das sonst als der Anfang einer Zeichenfolge in Anführungszeichen interpretiert würde, in doppelten Anführungszeichen ignoriert wird. Variablen werden jedoch interpretiert und durch ihre Werte in doppelten Anführungszeichen ersetzt.
$ echo "The current Oracle SID is $ORACLE_SID"
Es wird dies geben:
The current Oracle SID is test
Zurück Anführungszeichen sind völlig anders als einfache oder doppelte Anführungszeichen. Anstatt verwendet zu werden, um die Interpretation von Sonderzeichen zu verhindern, erzwingen hintere Anführungszeichen die Ausführung der von ihnen eingeschlossenen Befehle. Nachdem die beigefügten Befehle ausgeführt wurden, wird ihre Ausgabe anstelle der hinteren Anführungszeichen in der ursprünglichen Zeile ersetzt. Dies wird anhand eines Beispiels klarer.
Es gibt einen klaren Unterschied zwischen der Verwendung von ' 'und " ".
Wenn ' 'etwas verwendet wird, wird keine "Transformation oder Übersetzung" durchgeführt. Es wird so gedruckt, wie es ist.
Mit " ", was auch immer es umgibt, wird es in seinen Wert "übersetzt oder transformiert".
Mit Übersetzung / Transformation meine ich Folgendes: Alles innerhalb der einfachen Anführungszeichen wird nicht in ihre Werte "übersetzt". Sie werden so genommen, wie sie in Anführungszeichen stehen. Beispiel: a=23, dann echo '$a'produzieren wird $aauf der Standardausgabe. Während echo "$a"produziert 23auf der Standardausgabe.
Was meinst du mit "Übersetzung" oder "Transformation"?
Nico Haase
Diese Antwort ist ziemlich verwirrend und fügt nichts zu den vorhandenen guten Antworten hinzu.
Codeforester
2
Dies war meiner Meinung nach eine kurze, prägnante Antwort, ohne übermäßig wortreich zu sein, was für mich leicht zu verstehen war. Wenn Sie Übersetzung / Transformation sagen, bedeutet dies, dass doppelte Anführungszeichen die Variable erweitern, während einfache Anführungszeichen die Variable nicht erweitern.
B_e_n_n_y_
1
Ja, das ist die beste Antwort. Dies sollte die akzeptierte Antwort sein.
Jamey Kirby
3
Da dies die De-facto-Antwort beim Umgang mit Anführungszeichen in ist bash, werde ich einen weiteren Punkt hinzufügen, der in den obigen Antworten beim Umgang mit den arithmetischen Operatoren in der Shell übersehen wurde.
Die bashShell unterstützt zwei Arten der arithmetischen Operation, eine, die durch den integrierten letBefehl und den $((..))Operator definiert wird. Ersteres wertet einen arithmetischen Ausdruck aus, während letzteres eher eine zusammengesetzte Aussage ist.
Es ist wichtig zu verstehen, dass der arithmetische Ausdruck, der mit verwendet letwird, wie alle anderen Shell-Befehle einer wortaufteilenden Pfadnamenerweiterung unterzogen wird. Es muss also richtig zitiert und entkommen werden.
Siehe dieses Beispiel bei der Verwendung let
let 'foo = 2 + 1'
echo $foo3
Die Verwendung von einfachen Anführungszeichen ist hier absolut in Ordnung, da hier keine variablen Erweiterungen erforderlich sind. Betrachten Sie einen Fall von
bar=1
let 'foo = $bar + 1'
würde kläglich scheitern, da sich die $barunter einfachen Anführungszeichen nicht erweitern würden und doppelt in Anführungszeichen gesetzt werden müssen
let 'foo = '"$bar"' + 1'
Dies sollte einer der Gründe sein, die $((..))immer überbeansprucht werden sollten let. Weil der Inhalt darin keiner Wortaufteilung unterliegt. Das vorherige Beispiel mit letkann einfach geschrieben werden als
(( bar=1, foo = bar +1))
Denken Sie immer daran, $((..))ohne einfache Anführungszeichen zu verwenden
Obwohl das $((..))mit doppelten Anführungszeichen verwendet werden kann, hat es keinen Zweck, da es keinen Inhalt enthalten kann, der das doppelte Anführungszeichen benötigt. Stellen Sie einfach sicher, dass es nicht in einfachen Anführungszeichen steht.
In einigen besonderen Fällen, in denen der $((..))Operator in einer Zeichenfolge in einfachen Anführungszeichen verwendet wird, müssen Sie Anführungszeichen so interpolieren, dass der Operator entweder nicht in Anführungszeichen gesetzt oder in doppelte Anführungszeichen gesetzt wird. Stellen Sie sich beispielsweise einen Fall vor, in dem Sie versuchen, den Operator in einer curlAnweisung zu verwenden, um bei jeder Anforderung einen Zähler zu übergeben
Beachten Sie die Verwendung verschachtelter doppelter Anführungszeichen, ohne die die Literalzeichenfolge $((reqcnt++))an das requestCounterFeld übergeben wird.
Charles Duffy macht einen guten Fall hier für Doppel zitiert $((...))auch. Es mag "ein wenig" paranoid sein und es ist IFS=0zum Beispiel ziemlich unwahrscheinlich , aber es ist sicherlich nicht unmöglich :)
PesaThe
Es gibt auch die Legacy- $[[...]]Syntax, aber vielleicht haben Sie sie zu Recht vergessen.
Antworten:
Einfache Anführungszeichen interpolieren nichts, doppelte Anführungszeichen jedoch. Zum Beispiel: Variablen, Backticks, bestimmte Escapezeichen
\
usw.Beispiel:
Das Bash-Handbuch enthält Folgendes:
quelle
git_prompt
Git verwendenPS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
, das von Git bereitgestellt wird ? Sie schlagen vor, es wie folgt zu verwenden. Die Git-Eingabeaufforderung sollte demnach nicht funktionieren. Haben diePS#
Variablen etwas Besonderes ? oder warum funktioniert es, wenn es nicht die Interpolation macht.PS1
. Versucheecho $PS1
zu sehen, was ich meine. WirdPS1
jedoch vor der Anzeige ausgewertet (siehePROMPTING
Abschnitt in der Bash-Manpage). Versuchen Sie es, um dies zu testenPS1='$X'
. Sie werden keine Eingabeaufforderung haben. Dann laufenX=foo
und plötzlich ist Ihre Eingabeaufforderung "foo" (PS1
wurde ausgewertet, wenn eingestellt statt angezeigt , hätten Sie immer noch keine Eingabeaufforderung).Die akzeptierte Antwort ist großartig. Ich mache eine Tabelle, die zum schnellen Verständnis des Themas beiträgt. Die Erklärung beinhaltet eine einfache Variable
a
sowie ein indiziertes Arrayarr
.Wenn wir setzen
und dann
echo
den Ausdruck in der zweiten Spalte, würden wir das Ergebnis / Verhalten erhalten, das in der dritten Spalte gezeigt wird. In der vierten Spalte wird das Verhalten erläutert.Siehe auch:
$''
- GNU Bash Manual$""
- GNU Bash Manualquelle
The special parameters * and @ have special meaning when in double quotes
Wie kommt es also zu"*"
Ergebnissen*
?"$@"
und"$*"
sind Parametererweiterungen."@"
und"*"
sind nicht.echo "\'"
, gibt mich zurück\'
.Wenn Sie sich darauf beziehen, was passiert, wenn Sie etwas wiedergeben, geben die einfachen Anführungszeichen buchstäblich wieder, was Sie zwischen ihnen haben, während die doppelten Anführungszeichen Variablen zwischen ihnen auswerten und den Wert der Variablen ausgeben.
Zum Beispiel dies
wird dies geben:
quelle
Andere haben es sehr gut erklärt und wollen nur mit einfachen Beispielen geben.
Um Text können einfache Anführungszeichen verwendet werden, um zu verhindern, dass die Shell Sonderzeichen interpretiert. Dollarzeichen, Leerzeichen, kaufmännisches Und, Sternchen und andere Sonderzeichen werden ignoriert, wenn sie in einfache Anführungszeichen gesetzt werden.
Es wird dies geben:
Das einzige, was nicht in einfache Anführungszeichen gesetzt werden kann, ist ein einfaches Anführungszeichen.
Doppelte Anführungszeichen verhalten sich ähnlich wie einfache Anführungszeichen, außer dass doppelte Anführungszeichen es der Shell weiterhin ermöglichen, Dollarzeichen, hintere Anführungszeichen und umgekehrte Schrägstriche zu interpretieren. Es ist bereits bekannt, dass Backslashes die Interpretation eines einzelnen Sonderzeichens verhindern. Dies kann in doppelten Anführungszeichen hilfreich sein, wenn ein Dollarzeichen anstelle einer Variablen als Text verwendet werden muss. Außerdem können doppelte Anführungszeichen maskiert werden, damit sie nicht als Ende einer Zeichenfolge in Anführungszeichen interpretiert werden.
Es wird dies geben:
Es kann auch bemerkt werden, dass das Apostroph, das sonst als der Anfang einer Zeichenfolge in Anführungszeichen interpretiert würde, in doppelten Anführungszeichen ignoriert wird. Variablen werden jedoch interpretiert und durch ihre Werte in doppelten Anführungszeichen ersetzt.
Es wird dies geben:
Zurück Anführungszeichen sind völlig anders als einfache oder doppelte Anführungszeichen. Anstatt verwendet zu werden, um die Interpretation von Sonderzeichen zu verhindern, erzwingen hintere Anführungszeichen die Ausführung der von ihnen eingeschlossenen Befehle. Nachdem die beigefügten Befehle ausgeführt wurden, wird ihre Ausgabe anstelle der hinteren Anführungszeichen in der ursprünglichen Zeile ersetzt. Dies wird anhand eines Beispiels klarer.
Es wird dies geben:
quelle
Es gibt einen klaren Unterschied zwischen der Verwendung von
' '
und" "
.Wenn
' '
etwas verwendet wird, wird keine "Transformation oder Übersetzung" durchgeführt. Es wird so gedruckt, wie es ist.Mit
" "
, was auch immer es umgibt, wird es in seinen Wert "übersetzt oder transformiert".Mit Übersetzung / Transformation meine ich Folgendes: Alles innerhalb der einfachen Anführungszeichen wird nicht in ihre Werte "übersetzt". Sie werden so genommen, wie sie in Anführungszeichen stehen. Beispiel:
a=23
, dannecho '$a'
produzieren wird$a
auf der Standardausgabe. Währendecho "$a"
produziert23
auf der Standardausgabe.quelle
Da dies die De-facto-Antwort beim Umgang mit Anführungszeichen in ist
bash
, werde ich einen weiteren Punkt hinzufügen, der in den obigen Antworten beim Umgang mit den arithmetischen Operatoren in der Shell übersehen wurde.Die
bash
Shell unterstützt zwei Arten der arithmetischen Operation, eine, die durch den integriertenlet
Befehl und den$((..))
Operator definiert wird. Ersteres wertet einen arithmetischen Ausdruck aus, während letzteres eher eine zusammengesetzte Aussage ist.Es ist wichtig zu verstehen, dass der arithmetische Ausdruck, der mit verwendet
let
wird, wie alle anderen Shell-Befehle einer wortaufteilenden Pfadnamenerweiterung unterzogen wird. Es muss also richtig zitiert und entkommen werden.Siehe dieses Beispiel bei der Verwendung
let
Die Verwendung von einfachen Anführungszeichen ist hier absolut in Ordnung, da hier keine variablen Erweiterungen erforderlich sind. Betrachten Sie einen Fall von
würde kläglich scheitern, da sich die
$bar
unter einfachen Anführungszeichen nicht erweitern würden und doppelt in Anführungszeichen gesetzt werden müssenDies sollte einer der Gründe sein, die
$((..))
immer überbeansprucht werden solltenlet
. Weil der Inhalt darin keiner Wortaufteilung unterliegt. Das vorherige Beispiel mitlet
kann einfach geschrieben werden alsDenken Sie immer daran,
$((..))
ohne einfache Anführungszeichen zu verwendenObwohl das
$((..))
mit doppelten Anführungszeichen verwendet werden kann, hat es keinen Zweck, da es keinen Inhalt enthalten kann, der das doppelte Anführungszeichen benötigt. Stellen Sie einfach sicher, dass es nicht in einfachen Anführungszeichen steht.In einigen besonderen Fällen, in denen der
$((..))
Operator in einer Zeichenfolge in einfachen Anführungszeichen verwendet wird, müssen Sie Anführungszeichen so interpolieren, dass der Operator entweder nicht in Anführungszeichen gesetzt oder in doppelte Anführungszeichen gesetzt wird. Stellen Sie sich beispielsweise einen Fall vor, in dem Sie versuchen, den Operator in einercurl
Anweisung zu verwenden, um bei jeder Anforderung einen Zähler zu übergebenBeachten Sie die Verwendung verschachtelter doppelter Anführungszeichen, ohne die die Literalzeichenfolge
$((reqcnt++))
an dasrequestCounter
Feld übergeben wird.quelle
$((...))
auch. Es mag "ein wenig" paranoid sein und es istIFS=0
zum Beispiel ziemlich unwahrscheinlich , aber es ist sicherlich nicht unmöglich :)$[[...]]
Syntax, aber vielleicht haben Sie sie zu Recht vergessen.