Variable de entorno en / etc / environment con signo de libra (hash) en el valor

10

En Ubuntu 12.04, tengo una variable de entorno definida de /etc/environmentesta manera:

FOO="value_before#value_after"

Cuando ingreso al servidor para verificar el valor, obtengo esto:

$ env | grep FOO
FOO=value_before

Supongo que lo trata #como un comentario y lo elimina, sin embargo, esto funciona:

$ . /etc/environment
$ export FOO
$ env | grep FOO
FOO=value_before#value_after

He intentado escapar #así:

FOO="value_before\#value_after"

Pero eso no funciona, en cambio solo obtengo esto:

FOO=value_before\

¿Alguna idea sobre cómo hacer que el hash sea tratado como parte del valor? Cualquier ayuda sería genial.

Valores que he probado en el /etc/environmentarchivo:

FOO='value_before#value_after'
FOO="value_before#value_after"
FOO='"value_before#value_after"'
FOO="value_before\#value_after"
FOO='value_before\#value_after'

Y otras diversas combinaciones de lo anterior. Muchos de estos funcionarán cuando normalmente los configure en el shell. Pero no parecen funcionar en el /etc/environmentarchivo.

Jaymon
fuente

Respuestas:

5

Esto lo lee el módulo pam_env. Dado que el módulo pam_env espera que sean pares "simples" KEY = VALUE (no necesita comillas) y también admite comentarios identificados por #, se supone que un # y cualquier cosa que lo siga en un VALUE son un comentario. Además, tenga en cuenta que no admite ningún concepto de escape.

Esto se puede ver en el siguiente fragmento de la función _parse_env_file en pam_env.c .

/* now find the end of value */
mark = key;
while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0')
    mark++;
if (mark[0] != '\0')
    mark[0] = '\0';

El fragmento anterior recorre cada carácter de la porción de VALOR hasta que encuentra un \n, #o \0. Luego sobrescribe ese personaje con un \0.

Esto efectivamente elimina el #y todo lo que sigue. Nota: Esta es una característica, no un error. Es la característica de comentario.

Entonces, en este punto no puede tener valores /etc/environmentque incluyan a #o a \no \0en el medio del valor. También parece del código que las claves deben ser alfanuméricas.

Andrew De Ponte
fuente
Whoa, lo clavó! Gracias por la explicación detallada, he marcado esto como la solución aceptada.
Jaymon
3

Nunca pude encontrar una forma de evitar esta limitación en /etc/environment, la documentación parece indicar que /etc/environmentes un archivo de entorno simple :

This module can also parse a file with simple KEY=VAL pairs on separate 
lines (/etc/environment by default).

Lo que podría significar que no le permitirá escapar de los valores usando comillas o el \carácter, a pesar de que otros lugares en la documentación quizás digan que esto es posible :

(Possibly non-existent) environment variables may be used in values using 
the ${string} syntax and (possibly non-existent) PAM_ITEMs may be used in 
values using the @{string} syntax. Both the $ and @ characters can be 
backslash escaped to be used as literal values values can be delimited with ""

O tal vez no :

The file is made up of a list of rules, each rule is typically placed on a
single line, [...] Comments are preceded with `#´ marks and extend to the 
next end of line.

De todos modos, para evitar esta limitación, moví mis variables de entorno global a un archivo /etc/profile.dcomo se explica en esta respuesta . Todavía considero esta pregunta sin respuesta, pero quería asegurarme de que hubiera una solución alternativa para la posteridad.

Jaymon
fuente
1

No hay forma en / etc / environment para escapar del # (ya que se trata como un comentario) ya que está siendo analizado por el módulo PAM "pam_env" y lo trata como una simple lista de pares KEY = VAL y configura el entorno en consecuencia. No es bash / shell, el analizador no tiene lenguaje para hacer expansión variable o caracteres de escape.

Danila Ladner
fuente
0

Comillas simples.

$ FOO='foo#bar'
$ echo $FOO
foo#bar
Michael Hampton
fuente
1
Ese fue uno de los primeros valores que probé, aunque funciona en el shell, lamentablemente, no funciona /etc/environment, he actualizado mi pregunta con algunos ejemplos de valores que he probado.
Jaymon