46

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?

4 Answers 4

37

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.

26

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:

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

7
  • depending on whether you want this for interactive, login shells, bash-only, etc - can you clarify which one I use in which case, please?
    – Pedro A
    Mar 17, 2022 at 15:02
  • 1
    If it is generic env (e.g. JAVA_HOME or things like that) use profile. If it is specific to bash shell (e.g. setting up prompt) use bashrc if it is specific to zsh shell, use zshrc. If it is for you personally put it on the dotfiles in your home directory. If it needs to be a global (for all users on system) put it in environment/profile/bashrc/zshrc in /etc.
    – mattpr
    Mar 17, 2022 at 22:54
  • 1
    Login shell is going to be when you actually login and starts with the profile files and then bashrc or zshrc if the login shell starts one of these interactive shells (ie if you login over ssh with bash or zsh as your default shell) rather than just a GUI on desktop. Anytime you open a new terminal window you are starting a new interactive shell (zsh, bash, etc depending on what you have configured). Or you can just type bash or zsh from within an existing terminal in order to launch a new interactive shell from the previous one.
    – mattpr
    Mar 18, 2022 at 9:00
  • 1
    In order to better understand the order/troubleshoot you can add a specific env export to each env file and then inspect/print the value of that variable from different processes to see what order the files were loaded in and which files were loaded. Something like: THIS_ENV=/etc/profile; export ENV_LOAD_ORDER=$ENV_LOAD_ORDER:$THIS_ENV
    – mattpr
    Mar 18, 2022 at 9:04
  • 1
    Please also read the link from my answer (to a better answer) which covers this in more detail: askubuntu.com/a/247769/824160
    – mattpr
    Mar 18, 2022 at 9:06
5

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.

1
  • 1
    I believe this is a more reliable approach than editing the /etc/environment file as that file may be changed as packages are updated.
    – phreed
    Feb 12, 2019 at 23:20
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.

2
  • 4
    You can always do a source /etc/environment to reload it.
    – Panthro
    Aug 19, 2015 at 14:18
  • Logging out and back in should suffice.
    – karuhanga
    Dec 22, 2018 at 7:24

You must log in to answer this question.

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