Was sind in Bash die Unterschiede zwischen einfachen Anführungszeichen ( ''
) und doppelten Anführungszeichen ( ""
)?
Was sind in Bash die Unterschiede zwischen einfachen Anführungszeichen ( ''
) und doppelten Anführungszeichen ( ""
)?
Antworten:
Einfache Anführungszeichen interpolieren nichts, doppelte Anführungszeichen jedoch. Zum Beispiel: Variablen, Backticks, bestimmte Escapezeichen \
usw.
Beispiel:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Das Bash-Handbuch enthält Folgendes:
3.1.2.2 Einfache Anführungszeichen
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.3.1.2.3 Doppelte Anführungszeichen
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 ).
git_prompt
Git 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.
PS1
. Versuche echo $PS1
zu sehen, was ich meine. Wird PS1
jedoch vor der Anzeige ausgewertet (siehe PROMPTING
Abschnitt in der Bash-Manpage). Versuchen Sie es, um dies zu testen PS1='$X'
. Sie werden keine Eingabeaufforderung haben. Dann laufen X=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 Array arr
.
Wenn wir 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 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
---+-------------+-------------+--------------------------------------------------------------------
Siehe auch:
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
#!/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.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Es wird dies geben:
Monday, September 28, 2015
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 $a
auf der Standardausgabe. Während echo "$a"
produziert 23
auf der Standardausgabe.
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 integrierten let
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
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. Betrachten Sie einen Fall von
bar=1
let 'foo = $bar + 1'
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ü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 let
kann einfach geschrieben werden als
(( bar=1, foo = bar + 1 ))
$((..))
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.
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 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 curl
Anweisung zu verwenden, um bei jeder Anforderung einen Zähler zu übergeben
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Beachten Sie die Verwendung verschachtelter doppelter Anführungszeichen, ohne die die Literalzeichenfolge $((reqcnt++))
an das requestCounter
Feld übergeben wird.
$((...))
auch. Es mag "ein wenig" paranoid sein und es ist IFS=0
zum Beispiel ziemlich unwahrscheinlich , aber es ist sicherlich nicht unmöglich :)
$[[...]]
Syntax, aber vielleicht haben Sie sie zu Recht vergessen.