Setting global environment variable for everyone

If I set a variable in /etc/environment, it only seems to apply to administrators while in sudo su.

How can I get the variables to apply to everyone? Especially when they are in terminal? Do the settings in /etc/enviroment not apply to bash?


Solution 1:

The /etc/environment update will only work on the next session, it's not automatically reloaded.

Which means you cannot change it for sessions that have already started for other users.

If you want to "reload" whatever is in the /etc/environment you need the following command:

source /etc/environment

But again it will only work for your own current session, other users won't be affected until they start a new session or run the above command in their own session.

Solution 2:

TL;DR

These config files whether global (/etc/environment, /etc/profile) or user-specific (~/.profile, ~/.bashrc) only get processed on next login/session.

The global files apply to all users (not just root)...but you have to restart your login session to see the changes reflected in the environment. This can happen by calling su as you observed...or by logging out/in or rebooting. You could su to a non-root user and you would see they also have the environment changes.

The reason why you need to reboot or login again to get the global environment picked up is because environment is inherited from parent processes and the root process for everything else you run is your login shell...so if your login shell doesn't have the environment...then neither do the processes started within the login shell. You can of course set/update environment for individual processes as you start them but you would have to set the environment for the login shell and restart all sub processes for them to see the change.

Global Environment

As someone else mentioned, you need a reboot or logout/login for the changes to /etc/profile, /etc/profile.d/*.sh and /etc/environment to be picked up.

This is because while these files specify global environment...they are only run once at login and so existing logins/sessions won't reflect changes to those files. A reboot "resets" everyone's login forcing them to pickup the new environment.

In your own login session you can source /etc/profile in order to pickup the changes without a reboot or logout/login...but that will only affect your own session and new processes running within your session.

Note also that there is no variable interpolation in /etc/environment (it isn't a script) so you cannot do stuff like PATH="$PATH:/my/custom/path" there.

Note also that /etc/profile and /etc/profile.d/*.sh are only run for login sessions and so environment configured there won't be available to system non-login accounts (ie if you are trying to set an environmental variable for a daemon process that runs outside your login shell).

Note that bashrc is not useful for setting environment for the entire login shell but for bash shells and sub processes...so for true "global" or "user global" you probably want to put your environment config in /etc/profile or /etc/profile.d/my-custom-env.sh or ~/.profile. Other shells (e.g. zsh) have their own config files as well so non-bash-specific environment config in a bashrc will cause problems or confusion if/when you switch shells (or have other users on the system using different shells).

It is a common problem to install a new program and need to specify some environment for it to run properly. Global environment is one answer, but often will require a reboot which is not ideal for servers and auto-provisioning/configuring use cases. You should ask yourself whether this is really a variable that all users and programs on the system need or if it is really just something you need to make available to a specific user or program.

For specific user

look at including environment in profile or bashrc in the user's home directory (e.g. ~/.profile ~/.bashrc) depending on whether you want this for interactive, login shells, bash-only, etc.

Keep in mind that this also requires a reboot or logout/login for the environment changes to be available to all processes within the user's login session. The user can source ~/.profile...but that is done within a terminal and only updates the environment within that terminal session and child processes...not necessarily for the user's entire login environment.

For a specific program there are a couple options.

One is to just provide the environment when running the command:

VAR_NAME="VAR VALUE" VAR2_NAME="VAR2_VALUE" /path/to/program --opt1 --op2

If you are using systemd you can also specify the environment in the unit/service file under [Service] with Environment=VAR_NAME="VAR VALUE" VAR2_NAME="VAR2_VALUE

This option might feel clunky because you have to specify the environment each time you run a program, but if the environment is really only needed by that program...this is really the best way and you should get used to it and not dump everything into a bashrc or profile file.

If you aren't using systemd or init to setup environment and run the program...then of course you can also just wrap the program execution with a bash script where you save the full command including environment setup for convenience.

References:

  • https://help.ubuntu.com/community/EnvironmentVariables#System-wide_environment_variables
  • https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html
  • https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment=

There is also a very detailed answer here that I suggest you read: https://askubuntu.com/a/247769/824160

Solution 3:

Adding a variable to /etc/environment did work for me.

However I did have to reboot after changing /etc/environment for the change to take effect. Simply closing and re-opening the terminal window was not sufficient.

Solution 4:

create a custom shell script under

/etc/profile.d/

add your global environment variables inside your created script, reboot machine then it will be available to everyone.