Si bien las variables de entorno pueden tener cualquier nombre (incluida la cadena vacía) que no contenga un signo igual o un byte nulo, los shells asignan las variables de entorno a las variables de shell y, en la mayoría de los shells, los nombres de las variables están limitados a caracteres alfanuméricos ASCII y _
donde el primer carácter puede ' t ser un dígito (a excepción de los parámetros de posición y otras especiales como $*
, $-
, $@
, ..., (que no se asignan a las variables de entorno correspondientes)). También tenga en cuenta que algunas variables están reservadas / especiales por / al shell.
Excepciones a eso:
La rc
concha y sus derivados como es
y akanga
apoyar cualquier nombre excepto la cadena vacía, y las que son totalmente numérica o contener =
caracteres (y siempre exportan todas sus variables con el medio ambiente, y tener cuidado con las variables especiales como *
, status
, pid
...):
; '%$£"' = test
; echo $'%$£"'
test
; '' = x
zero-length variable name
;
Sin embargo, utiliza su propia codificación para variables cuyo nombre no contiene alnums o para matrices cuando se pasan en el entorno de comandos que se ejecutan:
$ 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
, yash
y zsh
(también bash
pero sólo para los caracteres de un solo byte) alnums de apoyo en la localización actual, no únicos ASCII.
$ Stéphane=1
$ echo "$Stéphane"
1
En esos shells, puede cambiar la configuración regional para considerar la mayoría de los caracteres como alfa, pero aún así no funcionaría para caracteres ASCII como .
. Puede engañar zsh
o ksh
pensar que £
es una letra, pero no ese .
o cualquier otro carácter ASCII (cuando se trata de permitir caracteres en nombres de variables, no para el [[:alpha:]]
glob por ejemplo).
ksh93
tiene variables especiales cuyo nombre contiene un punto como ${.sh.version}
, pero esas no están asignadas a variables de entorno y son especiales. El .
es asegurarse de que no entre en conflicto con otras variables. Si se hubiera elegido llamarlo $sh_version
, entonces podría haber potencialmente roto secuencias de comandos que utiliza esa variable ya (véase, por ejemplo, cómo zsh
tiene problemas con su $path
o $commands
variables especiales gama / de hash (a la CSH) que rompen algunos scripts).
Tenga en cuenta que, además de conchas que no soportan esas variables, algunas conchas como pdksh / mksh hacen eliminan desde el medio ambiente que reciben ( bash
elimina el uno con un nombre vacío, ash
, ksh
y bash
eliminar esas cadenas de entorno que no contienen un =
carácter):
$ 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 resumen, lo mejor es seguir con los nombres de variables con el apoyo de la mayoría de las conchas e incluso tratar de usar mayúsculas para las variables de entorno (y minúsculas o mayúsculas y minúsculas para las variables del shell no se exportan-) evitando aquellos que son especiales en conchas (como IFS
, PS1
, BASH_VERSION
...)
Si necesita establecer dicha variable en un shell que no las admite, pero no las descarta, puede volver a ejecutarlo usted mismo, con algo como:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(obviamente, si necesita hacerlo en el medio del script, eso no ayudará, pero podría echar un vistazo a ese enfoque para guardar y restaurar el entorno de ejecución de shell en un re-exec). O pruebe el enfoque del depurador:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(que se parece al trabajo con zsh
, yash
, csh
y tcsh
en AMD64 Linux, pero no con cualquiera de las otras conchas que probé ( mksh
, ksh93
, bash
, dash
)).