Environment variable in /etc/environment with pound (hash) sign in the value

On Ubuntu 12.04, I have an environment variable defined in /etc/environment like this:

FOO="value_before#value_after"

When I ssh into the server to check the value, I get this:

$ env | grep FOO
FOO=value_before

I'm guessing it is treating the # as a comment and stripping it out, however, this works:

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

I've tried escaping the # like this:

FOO="value_before\#value_after"

But that doesn't work, instead I just get this:

FOO=value_before\

Any ideas on how to make the hash be treated like part of the value? Any help would be great.

Values I've tried in the /etc/environment file:

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'

And other various combinations of the above. A lot of these will work when you just normally set them in the shell. But they don't seem to work in the /etc/environment file.


This is read by the pam_env module. Given that the pam_env module expects them to be "simple" KEY=VALUE pairs (doesn't need quotes) and also supports comments identified by #, it assumes that a # and anything following it in a VALUE are a comment. Also, note that it does not support any concept of escaping.

This can be seen in the following snippet from the _parse_env_file function in 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';

The above snippet walks each character of the VALUE portion until it finds a \n, # or \0. It then overwrites that character with a \0.

This effectively strips off the # and everything following. Note: This is a feature not a bug. It is the comment feature.

So, at this point you cannot have values in /etc/environment that include a # or a \n or \0 in the middle of the value. It also looks like from the code that the keys need to be alpha-numeric.


I was never able to find a way around this limitation in /etc/environment, the documentation seems to state that /etc/environment is a simple environment file:

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

Which might mean it won't let you escape values using quotes or the \ character, despite other places in the documentation maybe saying this is possible:

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

Or maybe not:

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.

Anyway, to get around this limitation, I moved my global environment variables into a file in /etc/profile.d as discussed in this answer. I still consider this question unanswered, but I wanted to make sure there was a linked workaround for posterity.


There is no way in /etc/environment to escape the #(as it treated as a comment) as it is being parsed by he PAM module "pam_env" and it treats it as a simple list of KEY=VAL pairs and sets up the environment accordingly. It is not bash/shell, the parser has no language for doing variable expansion or characters escaping.