You will probably want to edit your sudoers
file with sudo visudo
, find the line Defaults env_reset
and add a line Defaults env_keep = "JAVA_HOME"
below it. See below for explanation, details, and alternatives.
Why sudo
Is Clearing JAVA_HOME
When you run a command with sudo
, by default your environment is not passed intact. Most environment variables are removed, for security, and this is usually desirable. As man sudoers
says, in the section on "Command environment":
Since environment variables can influence program behavior, sudoers
provides a means to restrict which variables from the user's
environment are inherited by the command to be run. There are two
distinct ways sudoers
can deal with environment variables.
By default, the env_reset
option is enabled. This causes commands to
be executed with a new, minimal environment. On AIX (and Linux systems
without PAM), the environment is initialized with the contents of the
/etc/environment
file. The new environment contains the TERM, PATH,
HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in
addition to variables from the invoking process permitted by the
env_check
and env_keep
options. This is effectively a whitelist
for environment variables.
If, however, the env_reset option is disabled, any variables not
explicitly denied ....
Letting JAVA_HOME
Through One Time
One option, if you rarely run mvn spring-boot:run
as root and prefer not to change your configuration at all, is simply to pass on the value of JAVA_HOME
manually:
sudo JAVA_HOME="$JAVA_HOME" mvn spring-boot:run
When you run that:
- The shell performs parameter expansion and quote removal, replacing
"$JAVA_HOME"
with the value (i.e., contents) of JAVA_HOME
. If that contains no blank spaces, the quotes are not necessary (their purpose here is to prevent word splitting).
sudo
is called with three arguments: JAVA_HOME=...
, where ...
is the value of JAVA_HOME
when you ran the command; mvn
, and spring-boot:run
.
sudo
recognizes variable=value
syntax, and knows to run mvn
with JAVA_HOME
set to the specified value. (spring-boot:run
is passed as the first command-line argument to mvn
).
To pass all your environment variables through, you can run sudo -E mvn spring-boot:run
, but this is potentially less secure and not ideal because JAVA_HOME
is the only variable whose value you need preserved (besides the handful of variables whose values are automatically preserved even with env_reset
).
Letting JAVA_HOME
Through Every Time
Although you could disable env_reset
in your sudoers
file, this would pass almost all a user's environment variables through every time sudo
is run, and for this reason is not recommended.
Instead, I recommend you edit your sudoers
file and add an appropriate env_keep
line after the env_reset
line.
- Please do not edit
/etc/sudoers
directly. Instead, you should always use the visudo
command for this, which checks to ensure your syntax is correct (preventing the creation of an invalid sudoers
file which locks down sudo
until fixed).
Run:
sudo visudo
This will use your default command-line text editor. If you want to use a different editor, you can run visudo
with it assigned to the VISUAL
environment variable. For example:
sudo VISUAL=nano visudo
sudo VISUAL=gedit visudo
(VISUAL
isn't so named after the "vis" in visudo
; instead, it's the environment variable for specifying default text editors. You can also use the EDITOR
variable, but VISUAL
takes priority if set.)
Running visudo
opens up a temporary copy of your sudoers
file in a text editor; on exit, changes made to this copy are written to /etc/sudoers
.
Find the line that says:
Defaults env_reset
Add a line just under it, saying:
Defaults env_keep = "JAVA_HOME"
(If you already have an env_keep
line, add JAVA_HOME
to the quoted list of allowed variables. The variable names are separated from one another with spaces.)
Save the file and quit the text editor. Now, when users run commands with sudo
, the JAVA_HOME
environment variable will be preserved.
sudo echo $JAVA_HOME
without any problems. Why is that ? I did not modify the sudoers file btw – kranthi117 Apr 11 '15 at 03:02sudo echo $JAVA_HOME
, theJAVA_HOME
environment variable is evaluated as your user, not as root. Specifically, first the shell expands$JAVA_HOME
, before invoking thesudo
command.sudo
then receivesecho
as its first argument and the value (i.e., contents)JAVA_HOME
had in the calling shell's own environment as its second argument. One way to see the value of an environment variable when sudo'd to root is to run a root shell with sudo and make that shell evaluate it instead of the non-root calling shell:sudo sh -c 'echo $JAVA_HOME'
– Eliah Kagan Apr 11 '15 at 03:52