How do I make sudo preserve my environment variables?
Use carefully, there are security issues with sudo and variables.
From man sudoers
I found that you should use
Defaults env_reset Defaults env_keep += "PYTHONPATH OTHERVARIABLE YETANOTHER"
In Ubuntu, sudo
does preserves some variables. sudo -i
is more like logging in as root and then running the command.
Both may be inconvenient, the former for sudo nano myfile
leaves root-owned files inside your home and the latter for sudo -i nano myfile
will try to open /root/myfile.
Run
sudo printenv PATH
and see what it gives. Here it gives
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin
for example. Now run sudo visudo
and add the line
Defaults secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin
replacing by what you found just before. Append a new path to it if you need.
About libraries:
sudo LD_LIBRARY_PATH=/usr/lib/path/to/a/safe/library your command
Linux distributions take a lot of
care with PATH
, and you really should be careful before playing with it.
Be specially careful about adding paths like ".
" or /home/username
, it is unsecure.
One of the dangers of adding paths is that it opens for the possibility of files on these paths getting executed by root
, opening a windows in the system security that may be exploited by malicious software. There may be other dangers. Just make sure you know what you are doing. Bypassing sudo
security measures may render your Solaris as safe as Windows XP.
Fiddling with sudoers
is to be done with caution, as others have said.
A simpler approach for simpler cases when there are particular environment variables you want to preserve is to just pass the environment variable you want directly through sudo (this is shown as [VAR=value]
in the sudo cmdline help).
See this small example where I have also demonstrated it for more than one variable.
$ export MY_V1=1
$ export MY_V2=2
$ printenv | grep MY_V
MY_V2=2
MY_V1=1
$ sudo MY_V1=$MY_V1 MY_V2=$MY_V2 printenv | grep MY_V
MY_V2=2
MY_V1=1
For the original PYTHONPATH
example in the question, just use the following:
$ sudo PYTHONPATH=$PYTHONPATH python some_script.py
<script_output_here>
Creating an alias for this type of thing is handy. Like so:
$ alias sudopy='sudo PYTHONPATH=$PYTHONPATH python'
Your Defaults !env_reset
looks OK, assuming you're not also calling sudo with the -E
option.
You could try removing that entry completely.
Have you verified you're editing the correct sudoers file? I'm guessing it could be /etc/sudoers
or /usr/local/etc/sudoers
depending on how it was installed. Did you edit it using visudo
?
How are you running sudo? sudo python
, sudo su
, sudo su -
, sudo -s
, something else? Only sudo python
and sudo su
would preserve your environment.
What does env | grep PYTHONPATH
say? If nothing, make sure PYTHONPATH is exported by running export PYTHONPATH
and try again.
What does sudo env | grep PYTHONPATH
say? If it prints the expected value, then something else is overwriting your PYTHONPATH value. Maybe root's .bashrc or .bash_profile or the system-wide configuration files.