je peux écrire
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
le résultat final me semble à peu près le même. Pourquoi devrais-je écrire l'un ou l'autre? y en a-t-il qui ne sont pas portables / POSIX?
la source
je peux écrire
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
le résultat final me semble à peu près le même. Pourquoi devrais-je écrire l'un ou l'autre? y en a-t-il qui ne sont pas portables / POSIX?
VAR=$VAR1
est une version simplifiée de VAR=${VAR1}
. La seconde peut faire certaines choses que la première ne peut pas faire, par exemple référencer un index de tableau (non portable) ou supprimer une sous-chaîne (POSIX-portable). Voir la section Plus d'informations sur les variables du Guide Bash pour les débutants et le développement de paramètres dans les spécifications POSIX.
L'utilisation de guillemets autour d'une variable telle que rm -- "$VAR1"
ou rm -- "${VAR}"
est une bonne idée. Cela fait du contenu de la variable une unité atomique. Si la valeur de la variable contient des blancs (ainsi, des caractères dans la $IFS
variable spéciale, des blancs par défaut) ou des caractères globaux et que vous ne le citez pas, alors chaque mot est pris en compte pour la génération du nom de fichier (globbing) dont l'expansion multiplie autant d'arguments que vous le souhaitez. faites-vous.
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
Sur la portabilité: Selon POSIX.1-2008 section 2.6.2 , les accolades sont facultatives.
var1=$var
expansion donne une erreur?export VAR=$VAR1
. Quant aux accolades, elles sont facultatives (consultez le quatrième paragraphe de la section que vous avez citée; c'est le cas de tous les shells antérieurs à POSIX et POSIX).${VAR}
et$VAR
sont exactement équivalents. Pour un développement de variable simple, la seule raison à utiliser${VAR}
est le moment où l'analyse capturerait trop de caractères dans le nom de la variable, comme dans${VAR1}_$VAR2
(qui, sans accolades, équivaudrait à${VAR1_}$VAR2
). La plupart des extensions (parées${VAR:=default}
,${VAR#prefix}
...) nécessitent des accolades.Dans une affectation de variable, le fractionnement du champ ( par exemple le fractionnement à des espaces de la valeur) et l' expansion du chemin (c. -à- englobement) sont désactivés, donc
VAR=$VAR1
est exactement équivalente àVAR="$VAR1"
, dans toutes les coquilles POSIX et dans tous les poissons pré-Posix que je l' ai entendu parler de . (Réf. POSIX: commandes simples ). Pour la même raison,VAR=*
définit de manière fiableVAR
la chaîne littérale*
; bien sûrVAR=a b
metVAR
àa
puisque leb
est un mot séparé en premier lieu. En règle générale, les guillemets doubles ne sont pas nécessaires lorsque la syntaxe du shell attend un seul mot, par exemple, danscase … in
(mais pas dans le modèle), mais même là, vous devez faire attention: par exemple, POSIX spécifie queLes cibles de redirection (>$filename
) ne nécessitent pas de guillemets dans les scripts, mais quelques shells, y compris bash, requièrent les guillemets doubles, même dans les scripts. Voir Quand la double cotation est-elle nécessaire? pour une analyse plus approfondie.Vous avez besoin des guillemets dans d'autres cas, en particulier dans
export VAR="${VAR1}"
(ce qui peut être écrit de manière équivalenteexport "VAR=${VAR1}"
) dans de nombreux shells (POSIX laisse ce cas ouvert). La similitude de ce cas avec des affectations simples et la nature dispersée de la liste des cas dans lesquels vous n’avez pas besoin de guillemets, sont la raison pour laquelle je recommande d’utiliser des guillemets doubles à moins que vous ne souhaitiez scinder et glob.la source
IFS
caractère, car je veux en prendre l'habitude. La seule exception est que je ne cite pas la valeur lors d'une affectation de variable (sauf si requis, comme lorsque la valeur contient un espace). Cela rend la mise en évidence de la syntaxe de l'éditeur plus utile lorsqu'il existe des substitutions de commandes telles queFOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Plutôt que de tout colorer la couleur "chaîne", j'obtiens la coloration syntaxique du code imbriqué. C'est aussi pourquoi j'évite les backticks.>$file
est OK dans les scripts POSIX, il n'est pas dans bash même s'il n'est pas interactif (sauf si la conformité POSIX est appliquée avec$POSIXLY_CORRECT
ou--posix
...).VAR=$VAR1
, j'ai parfois été surpris par le faitlocal VAR=$VAR1
que je me souviens d'avoir travaillé différemment à certains égards, au moins dans certains obus. Mais atm, je ne peux pas reproduire la divergence.local VAR=$VAR1
est commeexport VAR=$VAR1
, cela dépend de la coquille.Citation
Considérez que les guillemets doubles sont utilisés pour les extensions variables et les guillemets simples pour les guillemets forts, c'est-à-dire sans expansion.
Expansion:
Sortie:
Il peut être intéressant de mentionner que vous devez utiliser la citation chaque fois que possible pour plusieurs raisons, dont la meilleure est qu’elle est considérée comme une pratique exemplaire et par souci de lisibilité. Aussi, parce que Bash est parfois bizarre et souvent pour des manières apparemment illogiques ou déraisonnables / inattendues, et que la citation modifie les attentes implicites en explicites, ce qui réduit cette surface d'erreur (ou son potentiel).
Et bien qu'il soit tout à fait légal de ne pas citer, et que cela fonctionne dans la plupart des cas, cette fonctionnalité est fournie pour plus de commodité et est probablement moins portable. la pratique entièrement formelle qui garantit de refléter l'intention et les attentes consiste à citer.
Substitution
Considérons maintenant que la construction
"${somevar}"
est utilisée pour les opérations de substitution. Plusieurs cas d'utilisation, tels que le remplacement et les tableaux.Remplacement (décapage):
Remplacement (remplacement):
Tableaux:
Tout cela ne fait qu’effleurer la surface de la
"${var}"
construction de substitution. La référence définitive pour les scripts shell Bash est la référence en ligne libre, TLDP The Linux Documentation Projecthttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
la source
fin ensuite:
mérite d'être cité comme exemple plus clair d'utilisation de curlies
la source