Variável de ambiente em / etc / environment com sinal de libra (hash) no valor

10

No Ubuntu 12.04, eu tenho uma variável de ambiente definida /etc/environmentassim:

FOO="value_before#value_after"

Quando ssh no servidor para verificar o valor, recebo o seguinte:

$ env | grep FOO
FOO=value_before

Eu estou supondo que está tratando o #como um comentário e retirando-o, no entanto, isso funciona:

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

Eu tentei escapar #assim:

FOO="value_before\#value_after"

Mas isso não funciona, em vez disso, apenas entendi:

FOO=value_before\

Alguma idéia de como fazer com que o hash seja tratado como parte do valor? Qualquer ajuda seria ótimo.

Valores que tentei no /etc/environmentarquivo:

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'

E outras várias combinações dos itens acima. Muitos deles funcionarão quando você apenas os define normalmente no shell. Mas eles não parecem funcionar no /etc/environmentarquivo.

Jaymon
fonte

Respostas:

5

Isso é lido pelo módulo pam_env. Dado que o módulo pam_env espera que sejam pares "simples" KEY = VALUE (não precisa de aspas) e também suporte comentários identificados por #, pressupõe que um # e qualquer coisa que o segue em um VALUE seja um comentário. Além disso, observe que ele não suporta nenhum conceito de escape.

Isso pode ser visto no seguinte trecho da função _parse_env_file em 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';

O trecho acima percorre cada caractere da parte VALUE até encontrar um \n, #ou \0. Em seguida, substitui esse caractere com a \0.

Isso efetivamente retira todos os #itens a seguir. Nota: Este é um recurso, não um bug. É o recurso de comentário.

Portanto, nesse ponto, você não pode ter valores /etc/environmentque incluem a #ou a \nou \0no meio do valor. Também parece no código que as teclas precisam ser alfanuméricas.

Andrew De Ponte
fonte
Whoa, acertou em cheio! Obrigado pela explicação detalhada, marquei isso como a solução aceita.
Jaymon
3

Eu nunca consegui encontrar uma maneira de contornar essa limitação /etc/environment, a documentação parece indicar que /etc/environmenté um arquivo de ambiente simples :

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

O que pode significar que não permitirá que você escape de valores usando aspas ou o \caractere, apesar de outros lugares na documentação estarem dizendo que isso é possível :

(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 ""

Ou talvez não :

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 qualquer forma, para contornar essa limitação, movi minhas variáveis ​​de ambiente global para um arquivo, /etc/profile.dconforme discutido nesta resposta . Ainda considero esta pergunta sem resposta, mas queria garantir que houvesse uma solução alternativa vinculada para a posteridade.

Jaymon
fonte
1

Não há como escapar do # (como tratado como um comentário) no / etc / environment, pois ele está sendo analisado pelo módulo PAM "pam_env" e o trata como uma lista simples de pares KEY = VAL e configura o ambiente em conformidade. Não é bash / shell, o analisador não possui linguagem para executar expansão variável ou caracteres que escapam.

Danila Ladner
fonte
0

Aspas simples.

$ FOO='foo#bar'
$ echo $FOO
foo#bar
Michael Hampton
fonte
1
Esse foi um dos primeiros valores que tentei, enquanto funciona no shell, infelizmente, não funciona /etc/environment. Atualizei minha pergunta com alguns exemplos de valores que tentei.
Jaymon