Назад | Перейти на главную страницу

Переменная среды в / etc / environment со знаком решетки (решетки) в значении

В Ubuntu 12.04 у меня есть переменная среды, определенная в /etc/environment как это:

FOO="value_before#value_after"

Когда я подключаюсь к серверу по ssh, чтобы проверить значение, я получаю следующее:

$ env | grep FOO
FOO=value_before

Я предполагаю, что это лечит # в качестве комментария и удаления его, однако, это работает:

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

Я пытался сбежать # как это:

FOO="value_before\#value_after"

Но это не работает, вместо этого я просто получаю следующее:

FOO=value_before\

Есть идеи о том, как сделать так, чтобы хеш считался частью значения? Любая помощь была бы замечательной.

Ценности, которые я пробовал в /etc/environment файл:

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'

И другие различные комбинации вышеперечисленного. Многие из них будут работать, если вы просто установите их в оболочке. Но они, похоже, не работают в /etc/environment файл.

Это читается модулем pam_env. Учитывая, что модуль pam_env ожидает, что они будут "простыми" парами KEY = VALUE (не нуждаются в кавычках), а также поддерживает комментарии, обозначенные #, он предполагает, что # и все, что следует за ним в VALUE, являются комментариями. Также обратите внимание, что он не поддерживает никаких концепций экранирования.

Это можно увидеть в следующем фрагменте из функции _parse_env_file в 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';

Приведенный выше фрагмент просматривает каждый символ части VALUE, пока не найдет \n, # или \0. Затем он перезаписывает этот символ с помощью \0.

Это эффективно удаляет # и все последующее. Примечание: Это особенность не Жук. Это функция комментариев.

Итак, на данный момент у вас не может быть значений в /etc/environment которые включают # или \n или \0 в середине значения. Из кода также видно, что клавиши должны быть буквенно-цифровыми.

Мне так и не удалось найти способ обойти это ограничение в /etc/environment, в документации указано, что /etc/environment это просто файл среды:

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

Это может означать, что он не позволит вам избежать значений, используя кавычки или \ характер, несмотря на другие места в документация, возможно, говорит, что это возможно:

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

А может и нет:

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.

В любом случае, чтобы обойти это ограничение, я переместил свои глобальные переменные среды в файл в /etc/profile.d так как обсуждается в этом ответе. Я до сих пор считаю этот вопрос без ответа, но я хотел убедиться, что существует связанный обходной путь для потомков.

В / etc / environment нет возможности избежать символа # (так как он рассматривается как комментарий), поскольку он анализируется модулем PAM «pam_env» и обрабатывает его как простой список пар KEY = VAL и устанавливает окружающей среды соответственно. Это не bash / shell, у парсера нет языка для расширения переменных или экранирования символов.

Одиночные кавычки.

$ FOO='foo#bar'
$ echo $FOO
foo#bar