Réponses:
Les guillemets simples n'interpoleront rien, mais les guillemets doubles le seront. Par exemple: variables, backticks, certaines \
échappées, etc.
Exemple:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Le manuel de Bash dit ceci:
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 ).
git_prompt
git 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.
PS1
. Essayez echo $PS1
de voir ce que je veux dire. Mais PS1
est évalué avant d'être affiché (voir la PROMPTING
section dans la page de manuel bash). Pour tester cela, essayez PS1='$X'
. Vous n'aurez aucune invite. Ensuite, exécutez X=foo
et 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).
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
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
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.
# | 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
---+-------------+-------------+--------------------------------------------------------------------
Voir également:
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
#!/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.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Cela donnera ceci:
Monday, September 28, 2015
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 $a
sur la sortie standard. Alors que echo "$a"
produira 23
sur la sortie standard.
É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 la let
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
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 $bar
guillemets 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 let
peut être simplement écrit comme
(( bar=1, foo = bar + 1 ))
$((..))
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.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
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
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Notez l'utilisation de guillemets doubles imbriqués à l'intérieur, sans lesquels la chaîne littérale $((reqcnt++))
est passée à requestCounter
field.
$((...))
. C'est peut-être "un peu" paranoïaque et très peu probable IFS=0
par exemple, mais ce n'est certainement pas impossible :)
$[[...]]
syntaxe héritée, mais vous avez peut-être eu raison de l'oublier.