it-swarm.com.de

Unterschied zwischen einfachen und doppelten Anführungszeichen in Bash

Was sind die Unterschiede zwischen einfachen Anführungszeichen ('') und doppelten Anführungszeichen ("") in Bash?

401
jrdioko

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. 

3.1.2.3 Anführungszeichen

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 ). 

430
Adam Batkin

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
198
likso

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:

165
codeforester

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 
4
Sree

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 ))

Denken Sie immer daran, $((..)) ohne Anführungszeichen zu verwenden

Obwohl $((..)) 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.

1
Inian

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.

0
a_ran