Exportar una variable con punto (.)

39

Cómo exportar una variable que tiene un punto. Recibo un 'nombre de variable no válido' cuando lo intento:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name

Incluso escapar del punto de metacaracteres (.) Tampoco ayudó

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier
usuario1587504
fuente
1
desafortunadamente no aparece en la lista cuando escribí / busqué una pregunta similar. lo siento. ..
user1587504

Respuestas:

50

Al menos para bashla página man 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 puede definir una variable como, my.homeya que no es un identificador válido.

Estoy muy seguro de que su ksh tiene una definición muy similar de un identificador y, por lo tanto, tampoco permite este tipo de variables. (Echa un vistazo a su página de manual).

También estoy muy seguro de que hay algún tipo de estándar general (POSIX?) Que especifica lo que está permitido como un identificador (y, por lo tanto, un nombre de variable).


Si realmente necesita este tipo de variable por alguna razón, puede usar algo como

env "my.home=/tmp/someDir" bash

para definirlo de todos modos. Pero, de nuevo, no podrá acceder a ella utilizando la sintaxis de shell normal. En este caso, probablemente necesite otro idioma como perl:

perl -e 'print $ENV{"my.home"}'

Por ejemplo

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'

debería imprimir tu camino.

michas
fuente
Es debido a la integración de la hormiga. Y desafortunadamente no permite establecer / exportar variables desde Unix. Aceptando tu respuesta. ..
user1587504
1
Ant suele estar configurado por una sola variable de entorno llamada ANT_OPTSo por ~ / .antrc. No hay necesidad de nombres de variables de entorno extraños para la hormiga misma.
michas
8

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 rcconcha y sus derivados como esy akangaapoyar 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, yashy zsh(también bashpero 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 zsho kshpensar 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).

  • ksh93tiene 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 zshtiene problemas con su $patho $commandsvariables 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 ( bashelimina el uno con un nombre vacío, ash, kshy basheliminar 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, cshy tcshen AMD64 Linux, pero no con cualquiera de las otras conchas que probé ( mksh, ksh93, bash, dash)).

Stéphane Chazelas
fuente
1
mksh(y pdksh) de hecho construyen los procesos de entorno que generan completamente desde cero, utilizando solo los parámetros exportados en el entorno de ejecución de shell actual, por lo que no hay forma de pasar esas variables a través de esos shells. (Tenga en cuenta que las variables que se pasan están sujetas a cambios; por ejemplo, estoy planeando admitir las exportaciones de matrices por mkshalgún día)
Mirabilos
0

Como señalan las otras publicaciones, los shells más comunes no permiten establecer variables de entorno con puntos en el nombre. Sin embargo, he encontrado situaciones, particularmente involucrando 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 a través de otros medios además de las variables de entorno. Por ejemplo, en Ant, puede usar el "-propertyfile (filename)" para pasar una colección formateada de valores-clave con formato de archivo de propiedades. Confd permite "-archivo de archivo de fondo (archivo yaml)".

Pasé las variables de entorno en la forma "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 setcomando, en Borne Shell, mostrará cada propiedad en una línea separada en el formulario

C__any_value='my.property.key=the value'

El awkcomando procesará solo las variables de entorno que comienzan con C__, luego extraerá los valores contenidos en las 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 de su propiedad o clave contendrá comillas simples, deberá cambiar el carácter separador de campo awk a 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á tomar medidas adicionales para decodificar el escape de la cotización.

Groboclown
fuente