56

I am trying to make a python environment separate from the system one (using virtualenv) in a directory which is not under /home, because I need to use it to build other software that has to be accessible to multiple users. I can create and activate the virtualenv all right, but when I sudo some command (for example to make or compile other software), it is the system python that is used (I can tell because of the available modules).

Since on Ubuntu it is not a good thing to use the root user, is there a way to tell sudo to use a virtualenv? Or maybe this is not the correct approach, and I should make a completely new python installation?

I am using the 64bit version of Ubuntu 12.04 (and python 2.7).

  • 1
    Does the following work? sudo $(which python) <script> – John Drinane May 26 '17 at 15:40
71

The issue is almost certainly that when you run sudo, the virtualenv environment variables, aliases, functions, etc aren't being carried over.

The solution would be to explicitly run the virtual environment's Python executable with sudo. For example if your virtualenv is ./AwesomeProject, then you could run sudo ./AwesomeProject/bin/python <script> to use the script with the virtualenv with root privileges.

| improve this answer | |
  • 4
    You could also let the first line of your script point to the Python binary in your virtualenv. #!<virtualenv_dir>/bin/python. – OrangeTux Sep 17 '13 at 14:04
  • Ugh, annoying that this is only solution so far. On Mac, sudo python uses python from the virtual env. – gaefan Oct 5 '19 at 19:56
  • @OrangeTux I tried what you suggested and it does not work for me when running the script with sudo python3 my_script.py – belvederef Feb 17 at 17:50
  • @kenkinder @gaefan In my case, I get Command not found when using sudo ./home/pradan/.virtualenvs/sk/bin/python3 main.py where main.py is my script and sk is name of my virtual env. – Pe Dro May 22 at 17:40
4

Just stumbled across this and for others who may find the same issue, Ken is correct that the env variables are not being carried over. The solution I used was to add the following lines to my script. This has the added benefit of always loading the virtual environment directly from the script. (Meaning you can use the script with crontab or launchd without any other workarounds.)

base_dir = os.path.dirname(os.path.abspath(__file__))
activate_this = os.path.join(base_dir, 'venv/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))

More background here: https://virtualenv.pypa.io/en/latest/userguide.html#using-virtualenv-without-bin-python

| improve this answer | |
4

Sometimes you need the $PATH updated because the script runs other programs. For example pypi-install needs py2dsc-deb in the PATH. This command works: sudo sh -c ". venv/bin/activate ; pypi-install $PACKAGE"

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.