ImportError only with sudo when running python app

2019-09-12 16:53发布

问题:

I'm trying to run some python code with the sudo command, but every time I do it, it gives me an Import error. However, if I run, say, import numpy in terminal it gives me no errors. Also, if I build a code with several Imports and then run it without the sudo command, it gives me no errors and the code runs flawlessly. I already added Defaults env_keep += "PYTHONPATH" to the sudoers folder, so that's not the problem. I installed Anaconda3, so maybe that's useful information?

I'm running GNOME Ubuntu 16.04.1 LTS. And kernel version 4.4.0-59-generic.

I'm sorry, I'm very new at this, but I'm learning.

I ran which python and then I ran sudo which python and they gave me different directories.

sudo which python gave me usr/bin/python which python gave me home/user/anaconda3/bin/python

I tried running sudo ./anaconda3/envs/ml/bin/python doc.py but now it says that it can't find the file.

I'm running it with sudo because I need the permission for docker to work.

EDIT: trying sudo -E instead of sudo yields the same error.

回答1:

The problem you have is that sudo does not follow the usual PATH order when looking at an executable: it searches the system directories first. This is written in the man sudo:

SECURITY NOTES sudo tries to be safe when executing external commands.

To prevent command spoofing, sudo checks "." and "" (both denoting current directory) last when searching for a command in the user's PATH (if one or both are in the PATH). Note, however, that the actual PATH environment variable is not modified and is passed unchanged to the program that sudo executes.

So, to fix this you have to make sure that the command you give to sudo cannot match a system executable, i.e. specify the absolute path:

sudo /home/user/anaconda3/bin/python

A general command that should work is:

sudo "$(which python)"

This is because which python is executed before sudo, and its output is passed as an argument to sudo. However sudo by default does not perform any "shell-like" setup, and may restrict the environment, so you may consider using the -E or -i flags to make sudo pass the environment untouched and do the proper shell setup.