[NCLUG] /etc/environment

Bob Proulx bob at proulx.com
Sun Aug 19 13:46:23 MDT 2007


Tim Swanson wrote:
> I'm trying to create a set of shared (all users) environment
> variables to locate my various software packages. I want to use the
> value of previously-defined variables in the new ones. For example:
> 
>   DEVELOPMENT_HOME=/usr/local/development
>   JAVA_PROJECT_HOME=$DEVELOPMENT_HOME/Java/projects

Okay.

> I started by editing the /etc/bash.bashrc file. That worked fine
> once I remembered to add "export". However, once I tried using the
> variables outside a terminal environment, they were no longer
> there. So in apps launched from the desktop environment, for
> example, I couldn't refer to them.

The /etc/bash.bashrc file is a good place to make system wide changes
for interactive bash shell environments.

> Some Googling convinced me that I needed to move the definitions to the 
> /etc/environment file.

The /etc/environment is an old IBM AIX feature that has been accepted
by PAM as a standard.  The PAM (pluggable authentication modules)
modules read /etc/environment.  But it is not a full shell and only
limited syntax is available.  Previously only NAME=VALUE pairs and
comments were allowed their.

This also meant that previously only PAM authenticated processes
included environment variables configured in /etc/environment.  It
used to be that system processes such as those started by init through
the /etc/init.d/* process did not include /etc/environment setting.
This has changed in recent years and now an attempt is usually made to
include /etc/environment configuration in /etc/init.d/* scripts too.

All of this should say that /etc/environment is not yet mature nor the
same everywhere.  I think some poking around would find a few holes
and corner cases pretty easily.  Use with caution.

> That worked, but when I put the definitions in as 
> above, the environment variables don't get recursively resolved. So I have 
> this problem:

Because PAM is not a full shell the full shell variable syntax is not
available.  I recommend avoiding it.

>   $ echo $DEVELOPMENT_HOME
>     /usr/local/development
> 
>   $ echo $JAVA_PROJECT_HOME
>     $DEVELOPMENT_HOME/Java/projects

Yep.  A literal NAME=VALUE setting.  The VALUE includes
$DEVELOPMENT_HOME and it was not expanded.

I know John suggested a `...` workaround but to me that does not seem
portable enough.  But if it works for you then fine.

> Can I do what I'm trying to do, or do I just have to define my environment 
> variables without using other environment variables? Why does this work in 
> /etc/bash.bashrc but not in /etc/environment?

At the core of the issue I think requiring the setting of environment
variables before something works to be the wrong direction.  For one
after installation the user would need to set the variable before the
setting was available.  I think for most people that would mean
logging out and back in again, akin to rebooting, yuck.

Instead I believe the Right Thing to do here is to create an entry
point that sets whatever environment may be necessary.

  #!/bin/sh
  export DEVELOPMENT_HOME=/usr/local/development
  export JAVA_PROJECT_HOME=$DEVELOPMENT_HOME/Java/projects
  exec myjavaprogram "$@"

If that script were installed in /usr/local/bin then it would be
immediately accessable to all users on the system.  No special user
environment configuration would be needed.  It is completely defined
behavior and no corner cases with odd systems would need to be worried
about.  Changes to the environment variables take effect immediately
upon the next invocation after a change whereas actually having them
in a user's environment would hang around there with the previous
value until they logout.

To me this is a much cleaner way to do things.  This is the direction
I recommend that you proceed and leave the user environment setting
problems behind.

Bob



More information about the NCLUG mailing list