Zmienna środowiskowa w / etc / environment z pound (hash) wpisz wartość

10

W systemie Ubuntu 12.04 mam zmienną środowiskową zdefiniowaną w /etc/environmentnastępujący sposób:

FOO="value_before#value_after"

Kiedy ssh do serwera, aby sprawdzić wartość, otrzymuję to:

$ env | grep FOO
FOO=value_before

Zgaduję, że traktuje to #jako komentarz i usuwa go, jednak działa to:

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

Próbowałem uciec w #ten sposób:

FOO="value_before\#value_after"

Ale to nie działa, zamiast tego otrzymuję to:

FOO=value_before\

Jakieś pomysły na to, jak sprawić, by skrót był traktowany jako część wartości? Każda pomoc byłaby świetna.

Wartości, które próbowałem w /etc/environmentpliku:

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'

I inne różne kombinacje powyższych. Wiele z nich będzie działać, gdy zwyczajnie ustawisz je w powłoce. Ale wydaje się, że nie działają w /etc/environmentpliku.

Jaymon
źródło

Odpowiedzi:

5

Odczytuje to moduł pam_env. Ponieważ moduł pam_env oczekuje, że będą to „proste” pary KLUCZ = WARTOŚĆ (nie wymagają cudzysłowów), a także obsługuje komentarze oznaczone przez #, zakłada, że ​​# i wszystko, co następuje po nim w WARTOŚCI, jest komentarzem. Zauważ też, że nie obsługuje żadnej koncepcji ucieczki.

Można to zobaczyć w następującym fragmencie funkcji _parse_env_file w 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';

Powyższy fragment prowadzi każdy znak w części WARTOŚĆ, aż znajdzie znak \n, #lub \0. Następnie zastępuje tę postać znakiem \0.

To skutecznie usuwa #wszystkie pozostałe elementy. Uwaga: Ta funkcja nie jest błędem. Jest to funkcja komentowania.

Tak więc w tym momencie nie możesz mieć wartości, /etc/environmentktóre obejmują a #lub a \nlub \0w środku wartości. Z kodu wynika również, że klawisze muszą być alfanumeryczne.

Andrew De Ponte
źródło
Zaraz, przybity! Dzięki za szczegółowe wyjaśnienie oznaczyłem to jako zaakceptowane rozwiązanie.
Jaymon,
3

Nigdy nie byłem w stanie znaleźć sposobu na obejście tego ograniczenia /etc/environment, dokumentacja wydaje się stwierdzać, że /etc/environmentjest to prosty plik środowiska:

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

Co może oznaczać, że nie pozwoli ci uciec od wartości za pomocą cudzysłowów lub \znaku, pomimo innych miejsc w dokumentacji, które mogą powiedzieć, że jest to możliwe :

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

A może nie :

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.

W każdym razie, aby obejść to ograniczenie, przeniosłem moje globalne zmienne środowiskowe do pliku w /etc/profile.dsposób omówiony w tej odpowiedzi . Nadal uważam, że na to pytanie nie ma odpowiedzi, ale chciałem się upewnić, że istnieje powiązane obejście dla potomności.

Jaymon
źródło
1

W / etc / environment nie ma sposobu na uniknięcie znaku # (traktowanego jako komentarz), ponieważ jest on analizowany przez moduł PAM „pam_env” i traktuje go jako prostą listę par KEY = VAL i konfiguruje środowisko odpowiednio. To nie jest bash / shell, parser nie ma języka do interpretacji zmiennych lub ucieczki znaków.

Danila Ladner
źródło
0

Pojedyncze cytaty.

$ FOO='foo#bar'
$ echo $FOO
foo#bar
Michael Hampton
źródło
1
To była jedna z pierwszych wartości, które wypróbowałem, chociaż działa w powłoce, niestety nie działa /etc/environment, zaktualizowałem swoje pytanie o kilka przykładów wartości, które wypróbowałem.
Jaymon