7

Is it valid to have "pointers" in /etc/environment using $FOO syntax? Right now my /etc/environment looks like this:

JAVA_HOME=/usr/lib/jvm/java-6-openjdk
MAVEN_HOME=/usr/bin/apache-maven/apache-maven-3.0.4
M2_HOME=$MAVEN_HOME
M2=$MAVEN_HOME/bin
PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:$JAVA_HOME/bin:$MAVEN_HOME/bin

I'm not getting the results that I'm expecting though:

~$ echo $JAVA_HOME
/usr/lib/jvm/java-6-openjdk
~$ echo $MAVEN_HOME
/usr/bin/apache-maven/apache-maven-3.0.4
~$ echo $PATH
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin/bin:/usr/games:$JAVA_HOME/bin:$MAVEN_HOME/bin

4 Answers 4

10

I didn't find much documentation on /etc/environment, but the reason things don't work the way you expect is that it's "not a script file", and thus is not processed by the shell, so referencing a previously-defined variable doesn't work. This explains the behaviour you're seeing.

You're better off defining these kinds of environment variables in your home, in .profile or .bashrc, or if you need them for all users, in /etc/profile.d or /etc/bash.bashrc.

There's some pretty extensive documentation on setting environment variables here, and it points to either .profile or .bashrc as the preferred place to put this stuff.

4
  • 2
    Thanks for the reply. From the post that you cited though: "Environment variable settings that affect the system as a whole (rather then just a particular user) should not be placed in any of the many system-level scripts that get executed when the system or the desktop session are loaded, but into /etc/environment - This file is specifically meant for system-wide environment variable settings. It is not a script file, but rather consists of assignment expressions, one per line. Specifically, this file stores the system-wide locale and path settings." Is that guidance incorrect? Jun 12, 2012 at 16:12
  • I'd say it's correct, however you'd lose the ability to reference a variable inside a definition, so you'd have to spell out the full JAVA_HOME and MAVEN_HOME in the PATH variable definition. If you want that, and you also want this to be available for all users, I'd say /etc/profile.d would be the place to put it, as it's designed so you can drop a separate file with your variables, thus you're not even modifying existing config files, so your changes should survive through upgrades.
    – roadmr
    Jun 12, 2012 at 18:56
  • Thanks, will either update the paths to the full/literal paths or will use one of those alternate files. Appreciate the help! Jun 13, 2012 at 3:11
  • My system doesn't have the file /etc/bash.bashrc. Has this file been moved somewhere else for ubuntu or is the only rc file loaded in bash on ubuntu the ~/.bashrc?
    – kapad
    Feb 12, 2018 at 17:20
4

The canonical source for the information you seek (at least for flavours of Debian that use SystemD; and derivatives thereof, such as modern versions of Ubuntu) is environment.d(5) (some formatting in this excerpt has been changed at my discretion for clarity):

Configuration format

The configuration files contain a list of KEY=VALUE environment variable assignments, separated by newlines. The right-hand side of these assignments may reference previously defined environment variables, using the ${OTHER_KEY} and $OTHER_KEY format. It is also possible to use ${FOO:-DEFAULT_VALUE} to expand in the same way as ${FOO} unless the expansion would be empty, in which case it expands to DEFAULT_VALUE, and use ${FOO:+ALTERNATE_VALUE} to expand to ALTERNATE_VALUE as long as ${FOO} would have expanded to a non-empty value. No other elements of shell syntax are supported.

Each KEY must be a valid variable name. Empty lines and lines beginning with the comment character # are ignored.

Example

Example 1. Setup environment to allow access to a program installed in /opt/foo

/etc/environment.d/60-foo.conf :–

FOO_DEBUG=force-software-gl,log-verbose
PATH=/opt/foo/bin:$PATH
LD_LIBRARY_PATH=/opt/foo/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}
2

You can use pointers in /etc/environment but have to use a different syntax:

try:

JAVA_HOME=/usr/lib/jvm/java-6-openjdk
MAVEN_HOME=/usr/bin/apache-maven/apache-maven-3.0.4
M2_HOME=${MAVEN_HOME}
M2=${MAVEN_HOME}/bin
PATH="/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:${JAVA_HOME}/bin:${MAVEN_HOME}/bin"

Use the curly braces {} around the variable names when referring to another variable assignment. So, instead of $JAVA_HOME, use ${JAVA_HOME}. It also seems to be necessary to have quotation marks around the value of a variable in which you have pointer to other variables:

so PATH="... ${SOME_VAR} ..."

3
  • 4
    I tried this, and it didn't seem to work for me. I get the literal ${FOO} in the path. May 15, 2013 at 23:04
  • 1
    This answer is incorrect, this does not work. Mar 7, 2016 at 13:10
  • /etc/environment is simply "read" or "loaded" but is never run as a script. It will only work for assignment. It won't work if you try to do script like things, for eg. M2_HOME=${MAVEN_HOME} and M2=${MAVEN_HOME}/bin
    – kapad
    Feb 12, 2018 at 17:18
1

The Ubuntu documentation makes this seem impossible. BUT, there is an answer.

ANSWER: Create persistent, system wide environment variables in /etc/bash.bashrc

JAVA_HOME="/tools/java"
...
PATH="$JAVA_HOME:$PATH"  

Details:
I posted a lengthier answer on this AskUbuntu question

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .