Setting user environment variable and apply it to new processes - linux

I'm trying to set a global environment variable by adding it to the .bash_profile.
What can I do (other than restarting), to apply this value globally, so that new processes (such as Eclipse) can access this value?
Also, if my goal is adding a global environment variable, is writing it to the users' .bash_profile the best way, that doesn't require sudo?

If you add something like this to your .bash_profile:
export MY_TEST_VAR=1213222
You can then execute .bash_profile again in the current shell context
. .bash_profile
And your new processes will see this new enviroment variable

Rebooting is not necessary if it's not root's profile you modified. You just need to log off from your desktop, or close all the sessions where you want the environment refreshed.
The user's profile files is the best way to set user-specific variables.
If you want system-wide or group-wide settings, those are best left to root (for system-wide) or a restricted set of users.
You could for example implement a scheme like this: Have files like the following:
/usr/local/etc/my_group.profile
readable by all users in mygroup but writable only by users of group mygroup_admins, and make the system-wide profile script source such files depending on the user's assigned groups. This gives you a bit of flexibility without having to hand out root privileges too much.

Related

Trying to understand how the PATH is set on linux (bash on Ubuntu 16.04)

EDIT
The answer to my question is actually obvious, I simply forgot about the meaning of the EXPORT keyword. I still drop the explanation here, just in case.
So in a few words, when opening a terminal with Ctrl-Alt T a new shell is created, which is a child of the shell created at loggin. As explained here, the loggin shell is initialized by reading /etc/profile, and as explained here and more specifically here elements of the environment are transmitted to child processes, notably variables prefixed with the EXPORT keyword.
I am trying to understand what is the mechanism under which the PATH is set under linux when opening a new (virtual) terminal.
I know one can change the PATH in several files (e.g. system : /etc/{profile, bash.bashrc, ... } or user: ~/{.profile, .bash_login, .bashrc... }, some of which are read at login, the others when opening new (virtual) terminals.
According to my tests, it seems the "profile" files are read at startup (when the user logs in), which registers some startup values for variables such as PATH. Then, each time a terminal is opened these startup values are provided to other script (e.g. bashrc) for further configuration, resulting in something like : PATH_IN_TERMINAL=$BASHRC_ADDONS:$PATH_FROM_PROFILE
Notably, ~/.profile won't normally be read after login. Changing this file won't have any effect in the current session and the PATH_FROM_PROFILE part of the PATH will remain the same until one logs in again (after logout or through ssh connection for instance).
Am I correct ? And if so, where can I find a doc on the subject ?
Thanks
This is the best explanation I have found on the subject: Startup Files
The simple explanation, in most common situations is:
Upon initial login to host, read /etc/profile followed by the first of
~/.bash_profile, ~/.bash_login or ~/.profile. ~/.profile is
supported by multiple shells, so is preferred.
When Bash starts, but not immediately after login, read ~/.bashrc.
So, profile files are intended to run upon login and should be used to print initial messages (e.g. Security Warning, Message of the Day), check mail, and configure settings/variables that rarely change. Either system-wide (quotas, MOTD, etc.), or user-specific (timezone, locale, terminal, etc.).
.bashrc files are intended for individual users to customize their interactive experience. e.g. defining aliases, setting prompts, adding to PATH, etc.
I almost always add source ~/.bashrc to the end of my .profile file so that my shell is always customized to my requirements, even immediately after login.
NOTE: The above only applies to interactive shells (e.g. running on a terminal). None of these files are read if bash is run non-interactively (e.g. via cron). In those cases, you should create a different file containing required variables and specify that via the BASH_ENV environment file.

How to ADD an environment variable that can be used by other process in Linux?

In a graphical DE, like KDE, what command can be used to add a new environment variable that can be used by any other process?
Note:
1) I'm aware of export A=B, but it only works for subsequent processes started in the same shell that executed the export, processes started else where, like a graphical application such as Chrome, won't be aware of the export.
2) I'm also aware that you can put it into ~/.bash_profile or alike, but that would need a restart/relogin for the setting to take effect.
Is there something like export but have effect for all applications and doesn't require a significant restart?
Your assumption that you need to restart after placing a variable definition (whether through an export statement or otherwise) in ~/.bash_profile, is flawed. You only need to source the file again after making modifications:
source ~/.bash_profile
or the more portable version:
. ~/.bash_profile
Either statement will (re)load any definitions in that file into your current shell. Sourcing is not the same as executing the script: it will modify the environment in the calling shell itself, not a subshell running the script.
A file like ~/.bash_profile may have many other definitions and settings in it that will mess with the shell. It is better to create a small (temporary) snippet with just the variables you want, and source that instead, as #JeremiahMegel suggests.
If you want to change the environment for a single process you run from the command line, you can set the variables on the same command line:
VAR=value /usr/bin/gedit
This will run gedit with the environment variable VAR set to value, but only for that one child process.
Unfortunately, your desktop applications are a bit more static than that. Most of the graphical applications you see in the menus are probably going to be represented by .desktop files in a folder like /usr/share/applications. These files are run in an environment that has almost none of the variables you are expecting. They rely on absolute paths, and most of the configuration is done by pointing the .desktop file to a script that performs its own setup. You can modify some of these files on an individual basis if you absolutely have to, but I would not recommend doing that. If you do insist on messing around with the graphical apps on your desktop, I would recommend making a copy of the desktop files you plan to modify in to ~/.local/share/applications, or whatever the equivalent is on your system. Those files will override anything found in /usr/share/applications and will only affect you.

How to include bash profile in etc

I have a .bash_profile created that contains the environmental variables set. This was created for a particular user, say user1. I now want to reuse this environment variables also for other users, but I do not want to create yet another .bash_profile. I have a postgres user to which I would like to share this .bash_profile.
I understand that I could do this with /etc/profile. How could I reference the .bash_profile in the /etc/profile?
Copy the common content to /etc/profile. This way, it will be available for all users when they log in.
In comments I mentioned that you can modify the /etc/profile file and add the following line: source /home/<some_user>/.bash_profile. This will make this file to be sourced by all users when they log in. DO NOT DO IT: it allows a single user subverting the entire system (see comments below by trojanfoe).

How to store specific options for node.js CLI tool?

I'm looking for a good practice there. I need to store some global config options in my node.js command-line tool.
For example typing in bash:
$: mycommand set myGlobalOption=value
and then I can use myGlobalOption with another commands, is storing this value in environment variable a good solution?
Store this in a configuration file in the user's home directory like ~/.myprog.json. You can't store persistent data in environment variables because those ultimately come from shell configuration files like ~/.bash_profile which are not machine editable. Allowing these values to be set by environment variables is reasonable, but just have the user set them herself and don't bother trying to have a set command like you describe.
You could also just take these options as command line arguments like mycommand --myglobaloption=value and let users who want to always use the same value set up a shell alias like alias mc="mycommand --myglobaloption=value".

How to programmatically set a permanent environment variable in Linux?

I am writing a little install script for some software. All it does is unpack a target tar, and then i want to permanently set some environment variables - principally the location of the unpacked libs and updating $PATH. Do I need to programmatically edit the .bashrc file, adding the appropriate entries to the end for example, or is there another way? What's standard practice?
Edit: The package includes a number of run scripts (20+) that all use these named environment variables, so I need to set them somehow (the variable names have been chosen such that a collision is extremely unlikely)
LSB-compliant (see spec) practice is to create a shell script in /etc/profile.d/ folder.
Name it after your application (and make sure that the name is unique), make sure that the name ends with .sh (you might want to add scripts for other shells as well) and export the variables you need in the script. All *.sh scripts from that directory are read at user login--the same time /etc/profile is sourced.
Note that this is not enforced by bash; rather, it's an agreement of sorts.
Standard practice is to install into directories already in the path and in the standard library directory, so there is no need to update these variables.
Updating .bashrc is a bit failure-prone, among other things; what if a user uses a different file or shell?
You can also generate and install a script that sets those variables. Users of your package then source that script or copy its contents to their own shell init file.

Resources