/etc/environment 中的环境变量,值中包含井号(哈希)

/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'

以及上述各种组合。当您在 shell 中正常设置它们时,其中许多组合都会起作用。但它们似乎在文件中不起作用/etc/environment

答案1

这是由 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

这有效地剥离了#及其后续的所有内容。笔记:这是一个功能不是一个 bug。这是评论功能。

因此,此时您不能在值中间/etc/environment包含 a#或 a\n或 的值\0。从代码来看,键也需要是字母数字。

答案2

我一直没能找到办法绕过这个限制/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在这个答案中讨论我仍然认为这个问题没有答案,但我想确保为后人提供一个相关的解决方法。

答案3

/etc/environment 中没有办法转义 #(因为它被视为注释),因为它正在由 PAM 模块“pam_env”解析,并且它将其视为 KEY=VAL 对的简单列表并相应地设置环境。它不是 bash/shell,解析器没有用于进行变量扩展或字符转义的语言。

答案4

单引号。

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

相关内容