Cómo exportar una variable que tiene un punto. Recibo un 'nombre de variable no válido' cuando intenté:
export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name
Incluso escapar del punto de metacarácter (.) tampoco ayudó
$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier
Respuesta1
Al menos para bash
la página de manual define la sintaxis de exportación como:
export [-fn] [name[=word]] ...
También define un "nombre" como:
name A word consisting only of alphanumeric characters and under‐
scores, and beginning with an alphabetic character or an under‐
score. Also referred to as an identifier.
Por lo tanto, realmente no se puede definir una variable como my.home
ya que no es un identificador válido.
Estoy muy seguro de que su ksh tiene una definición muy similar de identificador y, por lo tanto, tampoco permite este tipo de variables. (Eche un vistazo a su página de manual).
También estoy muy seguro de que existe algún tipo de estándar general (¿POSIX?) que especifica qué está permitido como identificador (y, por lo tanto, como nombre de variable).
Si realmente necesitas este tipo de variable por algún motivo, puedes usar algo como
env "my.home=/tmp/someDir" bash
definirlo de todos modos. Pero, de nuevo, no podrá acceder a él utilizando la sintaxis normal del shell. En este caso probablemente necesites otro lenguaje como perl:
perl -e 'print $ENV{"my.home"}'
Por ejemplo
env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'
debería imprimir su ruta.
Respuesta2
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 variables de entorno a variables de shell y, en la mayoría de los shells, los nombres de las variables se limitan a caracteres alfanuméricos ASCII y _
el primer carácter puede Será un dígito (excepto los parámetros posicionales y otros especiales como $*
,,, …, ( $-
que $@
no están asignados a las variables de entorno correspondientes)). También tenga en cuenta que algunas variables sonreservado/especialpor/al caparazón.
Excepciones a eso:
Al
rc
shell y sus derivados les gustaes
y admiten cualquier nombre excepto la cadena vacía, y aquellos queakanga
son completamente numéricos o contienen=
caracteres (y siempre exportan todas sus variables al entorno, y tengan 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 pasa en el entorno de los 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
yyash
(zsh
también,bash
pero solo para caracteres de un solo byte) admiten números en la configuración regional actual, no solo en ASCII.$ Stéphane=1 $ echo "$Stéphane" 1
En esos shells, podrías cambiar la configuración regional para considerar a la mayoría de los caracteres como alfa, pero aun así eso no funcionaría para caracteres ASCII como
.
. Puedes engañartezsh
oksh
pensar£
que es una letra, pero no esa.
ni ningún otro carácter ASCII (en lo que respecta a permitir caracteres en nombres de variables, no para el[[:alpha:]]
globo, por ejemplo).ksh93
tiene variables especiales cuyo nombre contiene un punto como${.sh.version}
, pero no están asignadas a variables de entorno y son especiales. El.
objetivo es asegurarse de que no entre en conflicto con otras variables. Si hubiera elegido llamarlo$sh_version
, entonces podría tener scripts potencialmente rotos que ya usaban esa variable (vea, por ejemplo, cómozsh
tiene problemas con sus$path
variables$commands
de matriz/hash especiales (a la csh) que rompen algunos scripts).
Tenga en cuenta que, además de los shells que no admiten esas variables, algunos shells como pdksh/mksh sí lo hacen.eliminardel entorno que reciben ( bash
elimina el que tiene un nombre vacío ash
y elimina aquellas cadenas ksh
de bash
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 admitidos por la mayoría de los shells e incluso intentar usar mayúsculas para las variables de entorno (y minúsculas o mixtas para las variables de shell no exportadas) evitando aquellos que son especiales en los shells (como IFS
, PS1
, BASH_VERSION
...).
Si necesita establecer dicha variable en un shell que no las admite, pero que no las descarta, puede volver a ejecutarlas usted mismo con algo como:
#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"
(Obviamente, si necesitas hacerlo en medio del guión, eso no ayudará, pero luego puedes echar un vistazo aese enfoquepara guardar y restaurar el entorno de ejecución del shell mediante una nueva ejecución). O pruebe el enfoque del depurador:
gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"
(ese parece funcionar con zsh
, y en Linux amd64, pero no con ninguno de los otros shells yash
que probé ( ,,,, ) ).csh
tcsh
mksh
ksh93
bash
dash
Respuesta3
Como señalan las otras publicaciones, los shells más comunes no permiten configurar variables de entorno con puntos en el nombre. Sin embargo, he encontrado situaciones, particularmente relacionadas con Docker y programas invocados, donde el software requería valores clave con puntos.
Sin embargo, en cada una de estas situaciones, esos pares clave-valor podrían pasarse al programa por otros medios además de las variables de entorno. Por ejemplo, en Ant, puede utilizar "-propertyfile (nombre de archivo)" para pasar una colección de valores-clave formateada en un archivo de propiedades. Confd permite "-archivo backend -file (archivo yaml)".
Pasé las variables de entorno en el formato "C__any_value='my.property.key=the value'". Luego cambié la invocación del programa para generar primero el archivo:
set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt
El set
comando, en Borne Shell, generará cada propiedad en una línea separada en el formulario
C__any_value='my.property.key=the value'
El awk
comando procesará solo las variables de entorno que comienzan con C__
y luego extraerá los valores contenidos entre comillas simples.
Este método requiere que el valor de la variable de entorno se establezca en la forma precisa que requiere el programa de procesamiento. Además, si el valor o la clave de su propiedad contendrá comillas simples, deberá cambiar el carácter separador del campo awk por algo que sepa que no aparecerá y rodear el valor con ese carácter. Por ejemplo, para usar %
como separador:
$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value
(La salida precisa dependerá de su shell). Deberá realizar pasos adicionales para decodificar la cita que se escapa.
Respuesta4
La respuesta de @michas es bastante correcta, pero es posible ampliarla para simular export
funciones con nombres de entorno de puntos.
Para "exportar" dicha variable, puede exec
actualizar el shell con env
el comando. Por ejemplo, para exportar test.env=foo
variables, utilice:
exec env "test.env=foo" $SHELL
Exec reemplazará el shell actual con un nuevo proceso, donde el nuevo proceso será una nueva instancia del shell actual ( $SHELL
) con una variable de entorno adicional test.env
(agregada por env "test.env=foo"
). Entonces, después de este comando puedes acceder a él desde tu proceso, por ejemplo:
perl -e 'print $ENV{"test.env"}'