在 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