932 Stimmen

Was sind die Unterschiede zwischen einfachen und doppelten Anführungszeichen in Bash?

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

3 Stimmen

Siehe dazu (eine mögliche plattformübergreifende Dublette): Was ist der Unterschied zwischen "...", '...', $'...' und $"..." Anführungszeichen? von Unix & Linux Stack Exchange.

3 Stimmen

Der Titel sagt Bash, aber das gilt wirklich für jede Bourne-kompatible Shell (klassische Bourne-Shell, POSIX sh, ash, dash, ksh, und - mit einigen Vorbehalten - zsh).

940voto

Adam Batkin Punkte 49295

Einfache Anführungszeichen werden nichts interpolieren, aber doppelte Anführungszeichen schon. Zum Beispiel: Variablen, Backticks, bestimmte \ Escapes usw.

Beispiel:

$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")

Das Bash-Handbuch sagt hierzu:

3.1.2.2 Single Quotes

Das Einklammern von Zeichen in einfachen Anführungszeichen (') bewahrt den wörtlichen Wert jedes Zeichens innerhalb der Anführungszeichen. Ein einfaches Anführungszeichen darf auch innerhalb von einfachen Anführungszeichen nicht auftreten, auch nicht wenn es von einem Backslash vorangestellt wird.

3.1.2.3 Double Quotes

Das Einklammern von Zeichen in doppelte Anführungszeichen (") bewahrt den wörtlichen Wert aller Zeichen innerhalb der Anführungszeichen, mit Ausnahme von $, `, \ und, wenn die Historienerweiterung aktiviert ist, !. Die Zeichen $ und ` behalten ihre spezielle Bedeutung in doppelten Anführungszeichen bei (siehe Shell-Expansions). Der Backslash behält seine spezielle Bedeutung nur bei gefolgt von einem der folgenden Zeichen: $, `, ", \ oder Zeilenumbruch. Innerhalb von doppelten Anführungszeichen werden Backslashes, die von einem dieser Zeichen gefolgt werden, entfernt. Backslashes, die Zeichen ohne besondere Bedeutung vorangehen, bleiben unverändert. Ein doppeltes Anführungszeichen kann innerhalb von doppelten Anführungszeichen durch ein vorangestellten Backslash zitiert werden. Wenn aktiviert, erfolgt die Historienerweiterung, es sei denn, ein in doppelten Anführungszeichen erscheinendes ! ist mit einem Backslash maskiert. Der vorangehende Backslash vor dem ! wird nicht entfernt.

Die speziellen Parameter * und @ haben eine besondere Bedeutung, wenn sie in doppelten Anführungszeichen stehen (siehe Shell Parameter Expansion).

106 Stimmen

Für alle, die nicht wissen, was "interpolieren" bedeutet: de.wikipedia.org/wiki/Zeichenketteninterpolation

1 Stimmen

Was ist, wenn Sie einen git_prompt verwenden, den git bereitstellt? Es wird vorgeschlagen, es so zu verwenden: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ', git prompt. Laut diesem sollte das nicht funktionieren. Gibt es etwas Besonderes an den PS# Variablen? Oder warum funktioniert es, wenn keine Interpolation erfolgt?

3 Stimmen

@ekiim Dieser genaue Text wird unverändert in PS1 eingestellt. Versuche echo $PS1, um zu sehen, was ich meine. Aber PS1 wird ausgewertet, bevor es angezeigt wird (siehe den PROMPTING Abschnitt in der Bash-Manpage). Um dies zu testen, versuche PS1='$X'. Du wirst keine Eingabeaufforderung haben. Führe dann X=foo aus und plötzlich lautet deine Eingabeaufforderung "foo" (wenn PS1 beim Setzen anstelle von Anzeigen ausgewertet worden wäre, hättest du immer noch keine Eingabeaufforderung).

688voto

codeforester Punkte 33470

Die akzeptierte Antwort ist großartig. Ich erstelle eine Tabelle, die beim schnellen Verständnis des Themas hilft. Die Erklärung beinhaltet eine einfache Variable a sowie ein indexiertes Array arr.

Wenn wir setzen

a=apfel          # eine einfache Variable
arr=(apfel)     # ein indexiertes Array mit einem Element

und dann den Ausdruck in der zweiten Spalte mit echo ausgeben, erhalten wir das Ergebnis / Verhalten, das in der dritten Spalte gezeigt wird. Die vierte Spalte erklärt das Verhalten.

#

Ausdruck

Ergebnis

Kommentare

1

"$a"

apfel

Variablen werden innerhalb von "" erweitert

2

'$a'

$a

Variablen werden innerhalb von '' nicht erweitert

3

"'$a'"

'apfel'

'' hat innerhalb von "" keine besondere Bedeutung

4

'"$a"'

"$a"

"" wird innerhalb von '' wörtlich behandelt

5

'\''

ungültig

ein ' kann innerhalb von '' nicht escaped werden; verwenden Sie "'" oder $'\'' (ANSI-C quoting)

6

"rot$arocks"

rot

$arocks erweitert nicht $a; verwenden Sie ${a}rocks, um $a zu erhalten

7

"rotapfel$"

rotapfel$

$ gefolgt von keinem Variablennamen ergibt $

8

'\"'

\"

\ hat innerhalb von '' keine besondere Bedeutung

9

"\'"

\'

\' wird innerhalb von "" interpretiert, hat aber keine Bedeutung für '

10

"\""

"

\" wird innerhalb von "" interpretiert

11

"*"

*

Glob funktioniert nicht innerhalb von "" oder ''

12

"\t\n"

\t\n

\t und \n haben innerhalb von "" oder '' keine besondere Bedeutung; verwenden Sie ANSI-C quoting

13

"`echo hallo`"

hallo

`` und $() werden innerhalb von "" ausgewertet (Backticks bleiben im tatsächlichen Output erhalten)

14

'`echo hallo`'

`echo hallo`

`` und $() werden innerhalb von '' nicht ausgewertet (Backticks bleiben im tatsächlichen Output erhalten)

15

'${arr[0]}'

${arr[0]}

Array-Zugriff innerhalb von '' ist nicht möglich

16

"${arr[0]}"

apfel

Array-Zugriff funktioniert innerhalb von ""

17

$'$a\''

$a'

Einfache Anführungszeichen können innerhalb des ANSI-C quoting escaped werden

18

"$'\t'"

$'\t'

Das ANSI-C quoting wird innerhalb von "" nicht interpretiert

19

'!befehl'

!befehl

Das History Expansion-Zeichen '!' wird innerhalb von '' ignoriert

20

"!befehl"

befehl args

expandiert zum letzten Befehl, der zu "befehl" passt

21

$'!befehl'

!befehl

Das History Expansion-Zeichen '!' wird innerhalb von ANSI-C Quotes ignoriert


Siehe auch:

2 Stimmen

Die akzeptierte Antwort besagt am Ende Die speziellen Parameter * und @ haben eine besondere Bedeutung, wenn sie in Anführungszeichen stehen, also wie kommt es dazu, dass "*" in * resultiert?

5 Stimmen

@Karl-AnderoMere, weil sie in diesem Fall überhaupt nicht als Parameter erweitert werden. "$@" und "$*" sind Parametererweiterungen. "@" und "*" sind es nicht.

0 Stimmen

@CharlesDuffy Vielen Dank, jetzt ergibt es Sinn!

262voto

likso Punkte 3270

Wenn Sie sich auf das beziehen, was passiert, wenn Sie etwas echoen, werden die einfachen Anführungszeichen wortwörtlich das ausgeben, was Sie zwischen ihnen haben, während die doppelten Anführungszeichen Variablen zwischen ihnen auswerten und den Wert der Variablen ausgeben werden.

Zum Beispiel, das hier

#!/bin/sh
MYVAR=sometext
echo "Doppelte Anführungszeichen geben Ihnen $MYVAR"
echo 'Einfache Anführungszeichen geben Ihnen $MYVAR'

wird das hier ausgeben:

Doppelte Anführungszeichen geben Ihnen sometext
Einfache Anführungszeichen geben Ihnen $MYVAR

28voto

Sreehari Punkte 385

Andere haben es sehr gut erklärt, und ich möchte nur etwas mit einfachen Beispielen geben.

Einfache Anführungszeichen können um Text herum verwendet werden, um zu verhindern, dass die Shell Sonderzeichen interpretiert. Dollarzeichen, Leerzeichen, Ka- undersand, Sterne und andere Sonderzeichen werden alle ignoriert, wenn sie in einfache Anführungszeichen eingeschlossen sind.

echo 'Allerlei Dinge werden in einfachen Anführungszeichen ignoriert, wie $ & * ; |.'

Es wird folgendes ausgegeben:

Allerlei Dinge werden in einfachen Anführungszeichen ignoriert, wie $ & * ; |.

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 immer noch erlauben, Dollarzeichen, Backticks und Backslashes zu interpretieren. Es ist bereits bekannt, dass Backslashes verhindern, dass ein einzelnes Sonderzeichen interpretiert wird. Dies kann innerhalb doppelter Anführungszeichen nützlich sein, wenn ein Dollarzeichen als Text anstelle einer Variablen verwendet werden muss. Es erlaubt auch doppelte Anführungszeichen zu escapen, damit sie nicht als das Ende einer zitierten Zeichenkette interpretiert werden.

echo "So können wir einfache ' und doppelte \" Anführungszeichen innerhalb von doppelten Anführungszeichen nutzen."

Es wird folgendes ausgegeben:

So können wir einfache ' und doppelte " Anführungszeichen innerhalb von doppelten Anführungs- zeichen nutzen.

Es kann auch bemerkt werden, dass das Apostroph, das sonst als Beginn einer zitierten Zeichenkette interpretiert werden würde, innerhalb doppelter Anführungszeichen ignoriert wird. Variablen hingegen werden innerhalb doppelter Anführungszeichen interpretiert und mit ihren Werten substituiert.

echo "Die aktuelle Oracle SID ist $ORACLE_SID"

Es wird folgendes ausgegeben:

Die aktuelle Oracle SID ist test

Backticks sind vollkommen anders als einfache oder doppelte Anführungszeichen. Anstatt verwendet zu werden, um die Interpretation von Sonderzeichen zu verhindern, zwingen Backticks tatsächlich die Ausführung der Befehle, die sie einschließen. Nachdem die eingeschlossenen Befehle ausgeführt wurden, wird ihre Ausgabe anstelle der Backticks in der originalen Zeile substituiert. Das wird klarer mit einem Beispiel.

today=`date '+%A, %B %d, %Y'`
echo $today

Es wird folgendes ausgegeben:

Montag, September 28, 2015

3 Stimmen

Ich mag diese Antwort, weil sie deutlich sagt Das einzige, was nicht in einfachen Anführungszeichen stehen kann, ist ein einfaches Anführungszeichen. Lass mich nur hinzufügen, dass Backticks veraltet sind, während $() POSIX-kompatibel ist, daher sollte man letzteres bevorzugen.

0 Stimmen

Ist das dasselbe wie today=$(date ...)?

0 Stimmen

@Ben ja, $(...) und `...` sind gleich. Außer dass das erste verschachtelt ist und das zweite nicht.

7voto

Inian Punkte 70880

Da dies die de-facto-Antwort auf das Umgängen mit Anführungszeichen in Bash ist, werde ich einen weiteren Punkt hinzufügen, der in den obigen Antworten übersehen wurde, nämlich den Umgang mit den arithmetischen Operatoren in der Shell.

Die Bash-Shell unterstützt zwei Möglichkeiten, arithmetische Operationen durchzuführen, eine definiert durch das integrierte let-Kommando und die andere der $((..))-Operator. Das erste wertet einen arithmetischen Ausdruck aus, während das letztere eher eine zusammengesetzte Anweisung ist.

Es ist wichtig zu verstehen, dass der arithmetische Ausdruck, der mit let verwendet wird, genauso wie andere Shell-Befehle Wortaufspaltung und Pfaderweiterung durchläuft. Daher müssen ordnungsgemäße Anführungszeichen und Escapes gesetzt werden.

Siehe dieses Beispiel bei der Verwendung von let:

let 'foo = 2 + 1'
echo $foo
3

Die Verwendung von einfachen Anführungszeichen ist hier absolut in Ordnung, da hier keine Variablenerweiterungen erforderlich sind. Betrachten Sie einen Fall von

bar=1
let 'foo = $bar + 1'

das wäre kläglich gescheitert, da das $bar unter einfachen Anführungszeichen nicht erweitern würde und doppelt angeführt werden müsste wie

let 'foo = '"$bar"' + 1'

Dies sollte einer der Gründe sein, warum $((..)) gegenüber let verwendet werden sollte. Da darin der Inhalt nicht der Wortaufspaltung unterliegt. Das vorherige Beispiel mit let kann einfach wie folgt geschrieben werden

(( bar=1, foo = bar + 1 ))

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

Auch wenn $((..)) mit doppelten Anführungszeichen verwendet werden kann, hat es keinen Zweck, da das Ergebnis nicht den Inhalt enthalten kann, der doppelte Anführungszeichen benötigen würde. Achten Sie einfach darauf, dass es nicht einfach angeführt ist.

printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): ungültige Nummer
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2

Vielleicht in einigen speziellen Fällen, in denen der $((..))-Operator innerhalb eines einfach angeführten Strings verwendet wird, müssen Anführungszeichen interpoliert werden, sodass der Operator entweder unangeführt oder unter doppelten Anführungszeichen steht. Zum Beispiel, wenn Sie versuchen, den Operator in einer curl-Anweisung zu verwenden, um jedes Mal, wenn eine Anfrage gestellt wird, einen Zähler zu übergeben, tun Sie folgendes

curl http://meinurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'

Bemerken Sie die Verwendung von verschachtelten doppelten Anführungszeichen darin, ohne die das buchstäbliche Zeichenfolge $((reqcnt++)) an das Feld requestCounter übergeben wird.

2 Stimmen

Charles Duffy führt hier einen guten Fall für das doppelte Zitieren von $((...)) an. Es mag "ein bisschen" paranoid und ziemlich unwahrscheinlich sein, IFS=0 zum Beispiel, aber es ist sicherlich nicht unmöglich :)

0 Stimmen

Es gibt auch die veraltete $[[...]] Syntax, aber vielleicht hattest du recht, sie zu vergessen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X