Debian – Setting environment variables in Linux for all processes

debianenvironment-variablesunix

I am using Ubuntu 9.1 (Karmic Koala) on my server.

A simple matter of setting environment variables so that they are globally available across all processes is driving me crazy and I'd appreciate some help!

I've tried setting them by using the export command in several different 'usual suspect' locations such as .bashrc, .bashrc, .profile. These work great for the shell itself and processes forked off the shell but not for processes started outside the shell (for example daemons kicked off at boot time or particularly annoying for me is that Mongrel launched by Capistrano doesn't seem to have these variables set and hence Ruby doesn't have access to them).

I've also tried some crazy ideas like setting them in a shell script and calling this script during boot time (via the update-rc.d method) to no avail.

In Windows, one can simply define a "system variable" which becomes available across all processes in the OS. How does one do this in Linux; specifically Debian based OS?

Best Answer

Processes (including shells) only inherit variables from their parents. There is no way to change them from the outside thereafter.

Set "global variables" as early in the boot (for system processes) or shell invocation (for user processes) as possible, or resign yourself to setting them in multiple places.

This may seem like a pain, but the ability to change another processes environment would be a bug, and would introduce all kinds of nasty race conditions.


What are you trying to do that you want "global" environment variables? There may be way to work around your problem.

Workaround:: Write a minimal script in your favorite shell format that only sets the variable you want and put it in a globally accessible place:

/etc/loglocaltion.sh:

export MY_LOG_DIR=/opt/share/mylog
export MY_DEFAULT_LOG_LEVEL=URGENT

and for everything that you want to use that configuration do one of

  1. launch it from shell which has sourceed loglocation.sh in it's non-interactive login file (the one that gets read for all instances of the shell, i.e. .bash_profile).
  2. write a minimal wrapper script which sources loglocation.sh before launching the real program. launchcorelogger.sh:

 

 CORELOGGER=/opt/sbin/mycorelogger
 source /etc/loglocation.sh
 exec $CORELOGGER

and have init run the script.

Now edits to the loglocation script will effect all associated processing if your run them from a fresh shell in the first case or restart them using you systems dameon restarted (/etc/init.d/mycorelogger restart or whatever).