Puis-je omettre en toute sécurité des guillemets à droite d'une affectation locale?
function foo {
local myvar=${bar}
stuff()
}
Je suis principalement intéressé par bash
, mais toute information sur les cas de coin dans d'autres coquilles sont les bienvenues.
Réponses:
Les cotes sont nécessaires
export foo="$var"
oulocal foo="$var"
(oureadonly
,typeset
,declare
et d' autres variables déclarant commandes ) en:dash
sh
de NetBSD (également basé sur le shell Almquist).sh
de FreeBSD 9.2 ou plus ancienne (voir la modification dans la 9.3 )yash
zsh
avec les versions antérieures à 5.1 inksh
oush
emulation (ou pourexport var="$(cmd)"
oùzsh
effectuerait le fractionnement des mots autrement (non globbing)).Comme dans le cas contraire, le développement des variables serait sujet à la division des mots et / ou à la génération du nom de fichier, comme dans tout argument d'une autre commande.
Et ne sont pas nécessaires dans:
bash
ksh
(toutes les implémentations)sh
de FreeBSD 9.3 ou plus récentesh
(depuis 2005)zsh
Dans
zsh
, split + glob n'est jamais utilisé lors du développement des paramètres, à moins que insh
ouksh
émulation, mais split (et non glob), lors de la substitution de commande. Depuis la version 5.1, les commandesexport
/local
et autres déclarations sont devenues des commandes doubles à mots clés / intégrées, comme dans les autres shells ci-dessus, ce qui signifie que les guillemets ne sont pas nécessaires, même danssh
/ksh
émulation et même pour la substitution de commandes.Il y a des cas spéciaux où la citation est nécessaire même dans ces coquilles bien que:
Ou plus généralement, si tout ce qui reste du
=
(y compris le=
) est cité ou le résultat d'une expansion (commeexport 'foo'="$var"
,export foo\="$var"
ouexport foo$((n+=1))="$var"
(qui$((...))
devrait également être cité en fait) ...). Ou en d'autres termes, lorsque l'argumentexport
ne serait pas une affectation de variable valide s'il était écrit sans leexport
.Si le
export
/local
nom de la commande elle - même est cité (même en partie comme"export" a="$b"
,'ex'port a="$b"
,\export a="$b"
, ou même""export a="$b"
), les guillemets autour$b
sont nécessaires , sauf pour AT & Tksh
etmksh
.Si
export
/local
ou une partie de celle-ci est le résultat d'une expansion (comme danscmd=export; "$cmd" a="$b"
ou mêmeexport$(:) a="$b"
) ou dans des choses commedryrun=; $dryrun export a="$b"
), alors les guillemets sont nécessaires dans chaque shell.Dans le cas de
> /dev/null export a="$b"
, les guillemets sont nécessaires danspdksh
et certains de ses dérivés.Car
command export a="$b"
, les guillemets sont nécessaires dans chaque shell maismksh
etksh93
(avec les mêmes mises en garde concernantcommand
etexport
ne résultant pas d'une certaine expansion).Ils ne sont nécessaires dans aucun shell lorsqu'ils sont écrits:
(Cette syntaxe étant également compatible avec le shell Bourne mais dans les versions récentes de
zsh
, ne fonctionne que danssh
/ksh
émulation).(notez que cela
var=value local var
ne devrait pas être utilisé car le comportement varie selon les coquilles).Notez également que l'utilisation
export
d'une affectation signifie également que le statut de sortie decmd
inexport var="$(cmd)"
est perdu. Le faire en tant queexport var; var=$(cmd)
n'a pas ce problème.Méfiez-vous également de ce cas particulier avec
bash
:Mon conseil serait de toujours citer.
la source
zsh
guillemets sont nécessaireslocal foo="$(cmd)"
car le fractionnement des mots (mais pas la génération du nom de fichier) est effectué pour les substitutions de commandes non entre guillemets (mais pas pour les extensions de paramètres non entreKSH_TYPESET
guillemets ), sauf si elle est activée, auquel cas les guillemets ne sont pas nécessaires. Avoir un sens? Non? Ensuite, citez toujours tout, sauf si vous savez exactement ce que vous faites.Je cite généralement toute utilisation de variables où il pourrait y avoir des caractères tels que des espaces blancs. Sinon, vous rencontrerez des problèmes comme celui-ci:
L'utilisation de la variable dans une affectation ne semble pas nécessiter les guillemets, mais lorsque vous allez l'utiliser comme dans le
printf
vous aurez besoin de le citer ici:Remarque: rappelez-vous que la variable
$IFS
est ce qui gouverne ce que sont les caractères de séparation.Exemple
Lorsque le débogage est activé dans Bash, nous pouvons voir ce qui se passe dans les coulisses.
Dans ce qui précède, nous pouvons voir que la variable, a bien
$bar
été transmise,$myvar
mais lorsque nous sommes allés utiliser,$myvar
nous devions être au courant du contenu de cette variable$myvar
.la source
bash
etksh
danslocal
/typeset
... builtins spéciaux).