Alors que les variables d'environnement peuvent avoir n'importe quel nom (y compris la chaîne vide) ne contenant ni signe égal ni octet nul, les shells mappent les variables d'environnement à des variables shell et, dans la plupart des shells, les noms de variables sont limités aux caractères alphanumériques ASCII _. t un chiffre (sauf pour les paramètres de position et d' autres comme ceux spéciaux $*, $-, $@, ..., (qui ne sont pas mis en correspondance avec les variables d'environnement correspondantes)). Notez également que certaines variables sont réservées / spéciales par / au shell.
Les exceptions à cela:
La rccoquille et ses dérivés comme eset akangaprennent en charge un nom , sauf la chaîne vide, et ceux qui sont tout numérique ou contiennent des =caractères (et toujours exporter toutes leurs variables à l'environnement, et méfiez - vous des variables spéciales comme *, status, pid...):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
Cependant, il utilise son propre codage pour les variables dont le nom ne contient pas d'alnums ou pour les tableaux lorsqu'il est passé dans l'environnement des commandes en cours d'exécution:
$ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
__2b=zzz$
__5f_=zzz$
a=zzz\001xxx$
$ env +=x rc -c "echo $'+'"
x
$ env __2b=x rc -c "echo $'+'"
x
AT & T ksh, yashet zsh(également bashmais uniquement pour les caractères à octet unique), prennent en charge les alnums dans les paramètres régionaux actuels, pas seulement ceux en ASCII.
$ Stéphane=1
$ echo "$Stéphane"
1
Dans ces shells, vous pouvez modifier les paramètres régionaux pour considérer la plupart des caractères comme des caractères alpha, mais cela ne fonctionnerait pas pour les caractères ASCII tels que .. Vous pouvez tromper zshou kshpenser que £c'est une lettre, mais pas cela .ni aucun autre caractère ASCII (où autoriser les caractères dans les noms de variables est concerné, pas pour le [[:alpha:]]glob par exemple).
ksh93a des variables spéciales dont le nom contient un point comme ${.sh.version}, mais celles-ci ne sont pas mappées à des variables d'environnement et sont spéciales. Le .est de s'assurer qu'il ne soit pas en conflit avec d'autres variables. Si elle avait choisi de l' appeler $sh_version, il aurait pu les scripts potentiellement cassés qui a utilisé cette variable déjà (voir par exemple comment zsha des problèmes avec son $pathou des $commandsvariables tableau spécial / hachage (à la csh) qui brisent certains scripts).
Notez que , en plus de coquilles qui ne supportent pas ces variables, des coquilles comme pdksh / mksh font supprimer les de l'environnement qu'ils reçoivent ( bashsupprime l'un avec un nom vide, ash, kshet bashsupprimer les chaînes d'environnement qui ne contiennent pas de =caractère):
$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%
$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%
En résumé, le mieux est de coller avec les noms de variables pris en charge par la plupart des coquilles et même essayer d'utiliser les majuscules pour les variables d'environnement (et minuscules ou majuscules et minuscules pour les variables shell non exportées) en évitant ceux qui sont spéciaux dans des coquilles (comme IFS, PS1, BASH_VERSION...)
Si vous devez définir une telle variable dans un shell qui ne la prend pas en charge, mais ne la supprime pas, vous pouvez soit réexécuter vous-même, avec quelque chose comme:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(Évidemment, si vous devez le faire au milieu du script, cela ne vous aidera pas, mais vous pourrez alors examiner cette approche pour enregistrer et restaurer l'environnement d'exécution du shell sur une nouvelle exécution). Ou essayez l'approche du débogueur:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(que l' on semble travailler avec zsh, yash, cshet tcshsur Linux AMD64, mais pas avec l' une des autres coquilles que j'ai essayé ( mksh, ksh93, bash, dash)).