Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are modules in PYTHONPATH not found when the containing directory is part of PYTHONPATH and file exists?

I have the following situation (verfication through commands below):

  • existing python script file in directory x
  • existing python cat __init__.py file in x
  • x added to PYTHONPATH variable availble for both logged in user and sudo

and I want to invoke ~/test.py with

#!/usr/bin/python
import sys;print sys.path;
import mount_utils
print "Hello World!"

with sudo python ~/test.py which causes

Traceback (most recent call last):
  File "/home/richter/test.py", line 3, in <module>
    import mount_utils
ImportError: No module named mount_utils

the directories in PYTHONPATH are not in sys.path except the current directory. python ~/test.py works as expected (prints sys.path and Hello World! to console). sudo -E python ~/test.py fails with the same error. I don't understand

  • Why the module isn't availble if PYTHONPATH variable is printed in sudo echo output
  • Why sudo -E doesn't preserve the environment (as far as I understand from man sudo and https://docs.python.org/2/using/cmdline.html there shouldn't be any difference between python bla and sudo -E python bla)

Why do I get this error?

Verification of situation in detail:

$ env | grep PYTHONPATH
PYTHONPATH=:/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib
$ sudo env | grep PYTHONPATH
$ LANG=C stat /home/richter/scripts/python/lib/mount_utils.py
  File: '/home/richter/scripts/python/lib/mount_utils.py'
  Size: 8374        Blocks: 24         IO Block: 4096   regular file
Device: 80ch/2060d  Inode: 20972052    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ richter)   Gid: ( 1000/ richter)
Access: 2014-08-19 17:06:37.542787417 +0200
Modify: 2014-07-31 10:54:14.709468668 +0200
Change: 2014-07-31 10:54:14.729478917 +0200
 Birth: -
$ LANG=C stat /home/richter/scripts/python/lib/__init__.py
  File: '/home/richter/scripts/python/lib/__init__.py'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 80ch/2060d  Inode: 20972114    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ richter)   Gid: ( 1000/ richter)
Access: 2014-08-09 19:49:44.345055332 +0200
Modify: 2014-05-07 06:57:31.434851243 +0200
Change: 2014-06-25 03:17:29.569551147 +0200
 Birth: -

I didn't get any idea from the quite similar unanswered question Why is PYTHONPATH being ignored?

EDIT 1: After considering How to set environment variable for everyone under my linux system? and the fact that echo ... is a rather bad way to ensure whether env variables are set, I put export PYTHONPATH="$PYTHONPATH:/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib" in

  • /etc/profile
  • /etc/profile.d/python_py.sh
  • /root/.bashrc
  • /home/richter/.bashrc

and now PYTHONPATH is (in addition to situation described above) available in env in sudo -i prompt, but not in sudo env | grep PYTHONPATH. sudo python test.py still fails due to the same error, i.e. my problems remains.

Also export PYTHONPATH="/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib" && sudo -E python test.py fails due to the same error.

like image 202
Kalle Richter Avatar asked Aug 19 '14 15:08

Kalle Richter


2 Answers

You need to add your PYTHONPATH environment variable to the sudoers env_keep.

Run:
sudo visudo (which opens the /etc/sudoers file in a safe way).

Add this line:
Defaults env_keep += "PYTHONPATH".

Now :wq, and that will preserve the PYTHONPATH variable when running sudo

like image 60
chown Avatar answered Oct 04 '22 14:10

chown


Could it be that the environment sudo is running under (root's) does not have the PYTHONPATH set?

sudo echo $PYTHONPATH

For this command, I think shell interpolation is hitting it before sudo executes so you are in essence just writing

sudo echo /home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib

which is really no different to

echo $PYTHONPATH

I can see you may be thinking along those lines with sudo -E (though I could not see specific output for that in your examples) - I don't personally have experience with sudo -E.

You could try

sudo 'echo $PYTHONPATH'

Where single quotes stop interpolation, and also

sudo -E 'echo $PYTHONPATH'

just in case when you are using sudo -E it is really just hitting the shell interpolation issue again...

//these suggestions are off top of my head, your mileage may vary!

like image 22
Matt Warren Avatar answered Oct 04 '22 15:10

Matt Warren