La présence de caractères entre guillemets simples ( ') préserve la valeur littérale de chaque caractère entre guillemets. Un guillemet simple ne peut pas apparaître entre guillemets simples, même lorsqu'il est précédé d'une barre oblique inverse.
Caractères Enfermer guillemets doubles ( ") préserve la valeur littérale de tous les caractères dans les citations, à l'exception de $, `, \et, lorsque l' expansion de l' histoire est activée, !. Les caractères $et `conservent leur signification particulière entre guillemets doubles (voir les extensions de shell ). La barre oblique inverse conserve sa signification que lorsqu'il est suivi d'un des caractères suivants: $, `, ",\ou nouvelle ligne. Dans les guillemets doubles, les barres obliques inverses suivies de l'un de ces caractères sont supprimées. Les barres obliques inverses précédant les caractères sans signification particulière ne sont pas modifiées. Un guillemet double peut être cité entre guillemets doubles en le précédant d'une barre oblique inverse. Si cette option est activée, l'expansion de l'historique sera effectuée, sauf si une !apparition entre guillemets doubles est échappée à l'aide d'une barre oblique inverse. La barre oblique inverse précédant le !n'est pas supprimée.
Les paramètres spéciaux *et @ont une signification particulière lorsqu'ils sont entre guillemets (voir Expansion des paramètres du shell ).
Qu'en est-il lorsque vous utilisez un git_promptgit fourni, ils suggèrent de l'utiliser comme ceci PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ', git prompt , selon cela ne devrait pas fonctionner. Y a-t-il quelque chose de spécial dans les PS#variables? ou pourquoi ça marche si ça ne fait pas l'interpolation.
ekiim
1
@ekiim Ce texte exact est défini (inchangé) dans PS1. Essayez echo $PS1de voir ce que je veux dire. Mais PS1est évalué avant d'être affiché (voir la PROMPTINGsection dans la page de manuel bash). Pour tester cela, essayez PS1='$X'. Vous n'aurez aucune invite. Ensuite, exécutez X=fooet tout à coup votre invite est "foo" (avait PS1été évaluée lorsqu'elle était définie au lieu d'être affichée, vous n'auriez toujours pas d'invite).
Adam Batkin
263
La réponse acceptée est excellente. Je fais un tableau qui aide à une compréhension rapide du sujet. L'explication implique une variable simple aainsi qu'un tableau indexé arr.
Si nous définissons
a=apple # a simple variable
arr=(apple)# an indexed array with a single element
puis echol'expression dans la deuxième colonne, nous obtiendrions le résultat / comportement affiché dans la troisième colonne. La quatrième colonne explique le comportement.
# | 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
---+-------------+-------------+--------------------------------------------------------------------
La réponse acceptée dit à la fin, The special parameters * and @ have special meaning when in double quotesalors comment se fait-il que les "*"résultats soient *?
anddero
2
@ Karl-AnderoMere, car ils ne sont pas du tout développés comme paramètres dans ce cas. "$@"et "$*"sont des extensions de paramètres. "@"et "*"ne le sont pas.
Charles Duffy
@CharlesDuffy Merci, c'est logique maintenant!
anddero
3
Numéro 9, echo "\'"me renvoie \'.
MaxGyver
@MaxGyver: merci de l'avoir pointé. J'ai mis à jour la réponse.
codeforester
233
Si vous faites référence à ce qui se passe lorsque vous faites écho à quelque chose, les guillemets simples feront littéralement écho à ce que vous avez entre eux, tandis que les guillemets doubles évalueront les variables entre eux et afficheront la valeur de la variable.
Par exemple, cette
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
donnera ceci:
double quotes gives you sometext
single quotes gives you $MYVAR
D'autres ont très bien expliqué et veulent juste donner des exemples simples.
Des guillemets simples peuvent être utilisés autour du texte pour empêcher le shell d'interpréter des caractères spéciaux. Les signes dollar, les espaces, les esperluettes, les astérisques et autres caractères spéciaux sont tous ignorés lorsqu'ils sont placés entre guillemets simples.
$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
Cela donnera ceci:
All sorts of things are ignored in single quotes, like $ &*;|.
La seule chose qui ne peut pas être mise entre guillemets simples est un guillemet simple.
Les guillemets doubles agissent de la même manière que les guillemets simples, sauf que les guillemets doubles permettent toujours au shell d'interpréter les signes dollar, les guillemets et les barres obliques inverses. Il est déjà connu que les barres obliques inverses empêchent l'interprétation d'un seul caractère spécial. Cela peut être utile entre guillemets doubles si un signe dollar doit être utilisé comme texte au lieu d'une variable. Il permet également d'échapper les guillemets doubles afin qu'ils ne soient pas interprétés comme la fin d'une chaîne entre guillemets.
$ echo "Here's how we can use single ' and double \" quotes within double quotes"
Cela donnera ceci:
Here's how we can use single ' and double " quotes within double quotes
On peut également remarquer que l'apostrophe, qui autrement serait interprétée comme le début d'une chaîne entre guillemets, est ignorée entre guillemets. Cependant, les variables sont interprétées et remplacées par leurs valeurs entre guillemets doubles.
$ echo "The current Oracle SID is $ORACLE_SID"
Cela donnera ceci:
The current Oracle SID is test
Les guillemets sont totalement différents des guillemets simples ou doubles. Au lieu d'être utilisés pour empêcher l'interprétation des caractères spéciaux, les guillemets arrière forcent en fait l'exécution des commandes qu'ils contiennent. Une fois les commandes jointes exécutées, leur sortie est remplacée à la place des guillemets dans la ligne d'origine. Ce sera plus clair avec un exemple.
Il existe une distinction claire entre l'utilisation de ' 'et " ".
Lorsqu'il ' 'est utilisé autour de quoi que ce soit, aucune "transformation ou traduction" n'est effectuée. Il est imprimé tel quel.
Avec " ", tout ce qui l'entoure, est "traduit ou transformé" en sa valeur.
Par traduction / transformation, je veux dire ce qui suit: Tout ce qui se trouve dans les guillemets simples ne sera pas "traduit" à leurs valeurs. Ils seront pris tels quels dans les guillemets. Exemple: a=23, puis echo '$a'produira $asur la sortie standard. Alors que echo "$a"produira 23sur la sortie standard.
Qu'entendez-vous par «traduction» ou «transformation»?
Nico Haase
Cette réponse est assez déroutante et n'ajoute rien en plus des bonnes réponses existantes.
codeforester
2
C'était une réponse concise courte à mon avis sans être trop verbeuse et facile à comprendre pour moi. Lorsque vous dites traduction / transformation, cela signifie que les guillemets doubles développeront la variable là où les guillemets simples ne développeront pas la variable.
B_e_n_n_y_
1
Oui, c'est la meilleure réponse. Ce devrait être la réponse acceptée.
Jamey Kirby
3
Étant donné que c'est la réponse de facto lorsque vous traitez avec des guillemets bash, j'ajouterai un autre point manquant dans les réponses ci-dessus, lorsque vous traitez avec les opérateurs arithmétiques dans le shell.
Le bashshell prend en charge deux méthodes de calcul arithmétique, l'une définie par la letcommande intégrée et l' $((..))opérateur. Le premier évalue une expression arithmétique tandis que le second est davantage une déclaration composée.
Il est important de comprendre que l'expression arithmétique utilisée avec letsubit une expansion de séparation de mots et de chemin comme toutes les autres commandes shell. Il faut donc bien citer et échapper.
Voir cet exemple lors de l'utilisation let
let 'foo = 2 + 1'
echo $foo
3
Utiliser des guillemets simples ici est tout à fait correct ici, car il n'y a pas besoin d'extensions de variables ici, considérons un cas de
bar=1
let 'foo = $bar + 1'
échouerait lamentablement, car les $barguillemets simples ne seraient pas développeraient et doivent être
let 'foo = '"$bar"' + 1'
Cela devrait être l'une des raisons, il $((..))faut toujours considérer l'utilisation excessive let. Parce qu'à l'intérieur, le contenu n'est pas sujet à la séparation des mots. L'exemple précédent utilisant letpeut être simplement écrit comme
(( bar=1, foo = bar +1))
N'oubliez pas d'utiliser $((..)) sans guillemets simples
Bien que le $((..))puisse être utilisé avec des guillemets doubles, il n'a aucun intérêt car il ne peut pas contenir un contenu qui aurait besoin du guillemet double. Assurez-vous simplement qu'il ne s'agit pas d'un guillemet simple.
Dans certains cas particuliers d'utilisation de l' $((..))opérateur à l'intérieur d'une seule chaîne entre guillemets, vous devez interpoler les guillemets de manière à ce que l'opérateur soit laissé entre guillemets ou entre guillemets doubles. Par exemple, considérons un cas, lorsque vous tentez d'utiliser l'opérateur à l'intérieur d'uncurl instruction pour passer un compteur chaque fois qu'une demande est faite, faites
Charles Duffy plaide également ici pour la double citation $((...)). C'est peut-être "un peu" paranoïaque et très peu probable IFS=0par exemple, mais ce n'est certainement pas impossible :)
PesaThe
Il y a aussi la $[[...]]syntaxe héritée, mais vous avez peut-être eu raison de l'oublier.
Réponses:
Les guillemets simples n'interpoleront rien, mais les guillemets doubles le seront. Par exemple: variables, backticks, certaines
\
échappées, etc.Exemple:
Le manuel de Bash dit ceci:
la source
git_prompt
git fourni, ils suggèrent de l'utiliser comme ceciPS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
, git prompt , selon cela ne devrait pas fonctionner. Y a-t-il quelque chose de spécial dans lesPS#
variables? ou pourquoi ça marche si ça ne fait pas l'interpolation.PS1
. Essayezecho $PS1
de voir ce que je veux dire. MaisPS1
est évalué avant d'être affiché (voir laPROMPTING
section dans la page de manuel bash). Pour tester cela, essayezPS1='$X'
. Vous n'aurez aucune invite. Ensuite, exécutezX=foo
et tout à coup votre invite est "foo" (avaitPS1
été évaluée lorsqu'elle était définie au lieu d'être affichée, vous n'auriez toujours pas d'invite).La réponse acceptée est excellente. Je fais un tableau qui aide à une compréhension rapide du sujet. L'explication implique une variable simple
a
ainsi qu'un tableau indexéarr
.Si nous définissons
puis
echo
l'expression dans la deuxième colonne, nous obtiendrions le résultat / comportement affiché dans la troisième colonne. La quatrième colonne explique le comportement.Voir également:
$''
- GNU Bash Manual$""
- GNU Bash Manualla source
The special parameters * and @ have special meaning when in double quotes
alors comment se fait-il que les"*"
résultats soient*
?"$@"
et"$*"
sont des extensions de paramètres."@"
et"*"
ne le sont pas.echo "\'"
me renvoie\'
.Si vous faites référence à ce qui se passe lorsque vous faites écho à quelque chose, les guillemets simples feront littéralement écho à ce que vous avez entre eux, tandis que les guillemets doubles évalueront les variables entre eux et afficheront la valeur de la variable.
Par exemple, cette
donnera ceci:
la source
D'autres ont très bien expliqué et veulent juste donner des exemples simples.
Des guillemets simples peuvent être utilisés autour du texte pour empêcher le shell d'interpréter des caractères spéciaux. Les signes dollar, les espaces, les esperluettes, les astérisques et autres caractères spéciaux sont tous ignorés lorsqu'ils sont placés entre guillemets simples.
Cela donnera ceci:
La seule chose qui ne peut pas être mise entre guillemets simples est un guillemet simple.
Les guillemets doubles agissent de la même manière que les guillemets simples, sauf que les guillemets doubles permettent toujours au shell d'interpréter les signes dollar, les guillemets et les barres obliques inverses. Il est déjà connu que les barres obliques inverses empêchent l'interprétation d'un seul caractère spécial. Cela peut être utile entre guillemets doubles si un signe dollar doit être utilisé comme texte au lieu d'une variable. Il permet également d'échapper les guillemets doubles afin qu'ils ne soient pas interprétés comme la fin d'une chaîne entre guillemets.
Cela donnera ceci:
On peut également remarquer que l'apostrophe, qui autrement serait interprétée comme le début d'une chaîne entre guillemets, est ignorée entre guillemets. Cependant, les variables sont interprétées et remplacées par leurs valeurs entre guillemets doubles.
Cela donnera ceci:
Les guillemets sont totalement différents des guillemets simples ou doubles. Au lieu d'être utilisés pour empêcher l'interprétation des caractères spéciaux, les guillemets arrière forcent en fait l'exécution des commandes qu'ils contiennent. Une fois les commandes jointes exécutées, leur sortie est remplacée à la place des guillemets dans la ligne d'origine. Ce sera plus clair avec un exemple.
Cela donnera ceci:
la source
Il existe une distinction claire entre l'utilisation de
' '
et" "
.Lorsqu'il
' '
est utilisé autour de quoi que ce soit, aucune "transformation ou traduction" n'est effectuée. Il est imprimé tel quel.Avec
" "
, tout ce qui l'entoure, est "traduit ou transformé" en sa valeur.Par traduction / transformation, je veux dire ce qui suit: Tout ce qui se trouve dans les guillemets simples ne sera pas "traduit" à leurs valeurs. Ils seront pris tels quels dans les guillemets. Exemple:
a=23
, puisecho '$a'
produira$a
sur la sortie standard. Alors queecho "$a"
produira23
sur la sortie standard.la source
Étant donné que c'est la réponse de facto lorsque vous traitez avec des guillemets
bash
, j'ajouterai un autre point manquant dans les réponses ci-dessus, lorsque vous traitez avec les opérateurs arithmétiques dans le shell.Le
bash
shell prend en charge deux méthodes de calcul arithmétique, l'une définie par lalet
commande intégrée et l'$((..))
opérateur. Le premier évalue une expression arithmétique tandis que le second est davantage une déclaration composée.Il est important de comprendre que l'expression arithmétique utilisée avec
let
subit une expansion de séparation de mots et de chemin comme toutes les autres commandes shell. Il faut donc bien citer et échapper.Voir cet exemple lors de l'utilisation
let
Utiliser des guillemets simples ici est tout à fait correct ici, car il n'y a pas besoin d'extensions de variables ici, considérons un cas de
échouerait lamentablement, car les
$bar
guillemets simples ne seraient pas développeraient et doivent êtreCela devrait être l'une des raisons, il
$((..))
faut toujours considérer l'utilisation excessivelet
. Parce qu'à l'intérieur, le contenu n'est pas sujet à la séparation des mots. L'exemple précédent utilisantlet
peut être simplement écrit commeN'oubliez pas d'utiliser
$((..))
sans guillemets simplesBien que le
$((..))
puisse être utilisé avec des guillemets doubles, il n'a aucun intérêt car il ne peut pas contenir un contenu qui aurait besoin du guillemet double. Assurez-vous simplement qu'il ne s'agit pas d'un guillemet simple.Dans certains cas particuliers d'utilisation de l'
$((..))
opérateur à l'intérieur d'une seule chaîne entre guillemets, vous devez interpoler les guillemets de manière à ce que l'opérateur soit laissé entre guillemets ou entre guillemets doubles. Par exemple, considérons un cas, lorsque vous tentez d'utiliser l'opérateur à l'intérieur d'uncurl
instruction pour passer un compteur chaque fois qu'une demande est faite, faitesNotez l'utilisation de guillemets doubles imbriqués à l'intérieur, sans lesquels la chaîne littérale
$((reqcnt++))
est passée àrequestCounter
field.la source
$((...))
. C'est peut-être "un peu" paranoïaque et très peu probableIFS=0
par exemple, mais ce n'est certainement pas impossible :)$[[...]]
syntaxe héritée, mais vous avez peut-être eu raison de l'oublier.