Was sind die Unterschiede zwischen einfachen Anführungszeichen (''
) und doppelten Anführungszeichen (""
) in Bash?
Bei einfachen Anführungszeichen wird nichts interpoliert, bei doppelten Anführungszeichen. Zum Beispiel: Variablen, Backticks, bestimmte \
-Escape-Zeichen usw.
Beispiel:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Das Bash-Handbuch hat folgendes zu sagen:
3.1.2.2 Einfache Anführungszeichen
Das Einschließen von Zeichen in einfache Anführungszeichen (
'
) behält den Literalwert jedes Zeichens in den Anführungszeichen bei. Ein einfaches Anführungszeichen darf nicht zwischen einfachen Anführungszeichen stehen, auch wenn ein Backslash vorangestellt ist.Das Einschließen von Zeichen in doppelte Anführungszeichen (
"
) behält den Literalwert aller Zeichen in den Anführungszeichen bei, mit Ausnahme von$
,`
,\
und, wenn die Erweiterung des Verlaufs aktiviert ist,!
. Die Zeichen$
und`
behalten innerhalb von Anführungszeichen ihre besondere Bedeutung (siehe Shell-Erweiterungen ). Der umgekehrte Schrägstrich behält seine besondere Bedeutung nur, wenn auf eines der folgenden Zeichen folgt:$
,`
,"
,\
oder Newline. In Anführungszeichen werden umgekehrte Schrägstriche entfernt, auf die eines dieser Zeichen folgt. Backslashes vorangestellter Zeichen ohne besondere Bedeutung bleiben unverändert. Ein Anführungszeichen kann in Anführungszeichen gesetzt werden, indem ein Backslash vorangestellt wird. Wenn aktiviert, wird die Erweiterung des Verlaufs ausgeführt, es sei denn, ein in doppelten Anführungszeichen vorkommender!
wird mit einem umgekehrten Schrägstrich maskiert. Der Backslash vor dem!
wird nicht entfernt.Die speziellen Parameter
*
und@
haben bei Anführungszeichen eine besondere Bedeutung (siehe Shell-Parametererweiterung ).
Wenn Sie sich auf das beziehen, was passiert, wenn Sie etwas wiederholen, geben die einfachen Anführungszeichen buchstäblich an, was Sie zwischen ihnen haben, während die doppelten Anführungszeichen Variablen zwischen ihnen auswerten und den Wert der Variablen ausgeben.
Zum Beispiel das
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
wird das geben:
double quotes gives you sometext
single quotes gives you $MYVAR
Die akzeptierte Antwort ist großartig. Ich erstelle eine Tabelle, die zum schnellen Verständnis des Themas beiträgt. Die Erklärung beinhaltet eine einfache Variable a
sowie ein indiziertes Array arr
.
Wenn wir uns setzen
a=Apple # a simple variable
arr=(Apple) # an indexed array with a single element
und dann echo
den Ausdruck in der zweiten Spalte, würden wir das Ergebnis/Verhalten in der dritten Spalte anzeigen. Die vierte Spalte erläutert das Verhalten.
# | 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 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"
---+-------------+-------------+--------------------------------------------------------------------
Siehe auch:
Andere haben es sehr gut erklärt und wollen es nur mit einfachen Beispielen geben.
Einfache Anführungszeichen kann für Text verwendet werden, um zu verhindern, dass die Shell Sonderzeichen interpretiert. Dollarzeichen, Leerzeichen, Et-Zeichen, Sternchen und andere Sonderzeichen werden ignoriert, wenn sie in einfachen Anführungszeichen stehen.
$ 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 einzelnes Anführungszeichen.
Doppelte Anführungszeichen verhalten sich ähnlich wie einfache Anführungszeichen, mit der Ausnahme, dass die Shell immer noch Dollarzeichen, Rückwärtszitate und umgekehrte Schrägstriche interpretiert. Es ist bereits bekannt, dass Backslashes die Interpretation eines einzelnen Sonderzeichens verhindern. Dies kann in Anführungszeichen hilfreich sein, wenn ein Dollarzeichen anstelle von Variablen als Text verwendet werden muss. Außerdem können doppelte Anführungszeichen mit Escapezeichen versehen werden, sodass sie nicht als Ende einer in Anführungszeichen angegebenen Zeichenfolge 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 der Apostroph, der andernfalls als Anfang einer in Anführungszeichen stehenden Zeichenfolge interpretiert würde, in doppelten Anführungszeichen ignoriert wird. Variablen werden jedoch interpretiert und durch doppelte Anführungszeichen ersetzt.
$ echo "The current Oracle SID is $Oracle_SID"
Es wird dies geben:
The current Oracle SID is test
Back Quotes sind völlig anders als einfache oder doppelte Anführungszeichen. Anstatt die Interpretation von Sonderzeichen zu verhindern, erzwingen back Anführungszeichen die Ausführung der Befehle, die sie enthalten. Nachdem die eingeschlossenen Befehle ausgeführt wurden, wird deren Ausgabe anstelle der Anführungszeichen in der ursprünglichen Zeile ersetzt. Dies wird anhand eines Beispiels klarer.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Es wird dies geben:
Monday, September 28, 2015
Da dies die de-facto-Antwort ist, wenn es um Zitate in bash
geht, füge ich noch einen Punkt hinzu, der in den Antworten oben fehlt, wenn es um die Rechenoperatoren in der Shell geht.
Die bash
-Shell unterstützt zwei Arten der Rechenoperation, eine, die durch den integrierten let
-Befehl und den $((..))
-Operator definiert wird. Ersteres wertet einen arithmetischen Ausdruck aus, während letzterer eher eine zusammengesetzte Anweisung ist.
Es ist wichtig zu verstehen, dass der mit let
verwendete arithmetische Ausdruck ebenso wie alle anderen Shell-Befehle der Erweiterung des Pfadnamens, dem Pfadnamen, unterzogen wird. Daher muss ein korrektes Zitieren und Fluchen erfolgen.
Siehe dieses Beispiel, wenn Sie let
verwenden.
let 'foo = 2 + 1'
echo $foo
3
Die Verwendung von einfachen Anführungszeichen ist hier absolut in Ordnung, da hier keine variablen Erweiterungen erforderlich sind
bar=1
let 'foo = $bar + 1'
würde fehlschlagen, da der $bar
unter einfachen Anführungszeichen nicht expandieren würde und als doppelt zitiert werden muss
let 'foo = '"$bar"' + 1'
Dies sollte einer der Gründe sein, die $((..))
sollte immer bei der Verwendung von let
in Betracht gezogen werden. Denn der Inhalt unterliegt nicht der Wortaufteilung. Das vorherige Beispiel mit let
kann einfach als geschrieben werden
(( bar=1, foo = bar + 1 ))
$((..))
ohne Anführungszeichen zu verwendenObwohl $((..))
mit doppelten Anführungszeichen verwendet werden kann, gibt es keinen Zweck, da das Ergebnis nicht einen Inhalt enthalten kann, der das doppelte Anführungszeichen benötigt. Stellen Sie nur sicher, dass es nicht einzeln zitiert ist.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
In einigen speziellen Fällen der Verwendung des $((..))
-Operators in einer einfachen Zeichenfolge mit Anführungszeichen müssen Sie Anführungszeichen so interpolieren, dass der Operator entweder nicht in Anführungszeichen gesetzt oder in doppelte Anführungszeichen gesetzt wird. Z.B. Betrachten Sie einen Fall, wenn Sie den Operator innerhalb einer curl
-Anweisung verwenden, um bei jeder Anforderung einen Zähler zu übergeben
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Beachten Sie die Verwendung von geschachtelten Anführungszeichen, ohne die die Literalzeichenfolge $((reqcnt++))
an das Feld requestCounter
übergeben wird.
Es besteht ein klarer Unterschied zwischen der Verwendung von ' '
und " "
.
Wenn ' '
um irgendetwas verwendet wird, erfolgt keine "Umwandlung oder Übersetzung". Es wird so gedruckt, wie es ist.
Mit " "
wird alles, was es umgibt, in seinen Wert "übersetzt oder umgewandelt".
Mit Übersetzung/Transformation meine ich Folgendes: Alles, was in den einfachen Anführungszeichen steht, wird nicht in ihre Werte "übersetzt". Sie werden so übernommen, wie sie in Anführungszeichen stehen. Beispiel: a=23
, dann erzeugt echo '$a'
bei der Standardausgabe $a
. Während echo "$a"
in der Standardausgabe 23
erzeugt.