Переменная окружения в / etc / environment со знаком фунта (хеша) в значении

10

В 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файле.

Jaymon
источник

Ответы:

5

Это читается модулем 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которые включают a #или a \nили \0в середине значения. Из кода также видно, что ключи должны быть буквенно-цифровыми.

Эндрю Де Понте
источник
Вау, прибил это! Спасибо за подробное объяснение, я отметил это как принятое решение.
Джеймон
3

Мне никогда не удавалось найти способ обойти это ограничение /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как обсуждалось в этом ответе . Я до сих пор считаю этот вопрос без ответа, но я хотел убедиться, что есть связанный обходной путь для потомков.

Jaymon
источник
1

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

Данила Ладнер
источник
0

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

$ FOO='foo#bar'
$ echo $FOO
foo#bar
Майкл Хэмптон
источник
1
Это было одно из первых значений, которые я попробовал, хотя он работает в оболочке, к сожалению, он не работает /etc/environment, я обновил свой вопрос несколькими примерами значений, которые я пробовал.
Джеймон