为什么PYTHONPATH中的模块无法找到,尽管包含目录在PYTHONPATH中且文件存在?
我遇到了以下情况(通过下面的命令验证):
- 在目录x中有一个现成的python脚本文件
- 在x中有一个现成的python
__init__.py
文件 - 目录x已经添加到
PYTHONPATH
变量中,这个变量对当前用户和sudo
都可用
我想用以下命令运行~/test.py
:
#!/usr/bin/python
import sys;print sys.path;
import mount_utils
print "Hello World!"
使用sudo python ~/test.py
,结果出现了:
Traceback (most recent call last):
File "/home/richter/test.py", line 3, in <module>
import mount_utils
ImportError: No module named mount_utils
在PYTHONPATH
中的目录没有出现在sys.path
中,除了当前目录。直接用python ~/test.py
可以正常工作(在控制台打印sys.path
和Hello World!
)。而sudo -E python ~/test.py
也失败了,错误信息和之前一样。我不明白:
- 为什么模块不可用,尽管在
sudo echo
的输出中可以看到PYTHONPATH
变量 - 为什么
sudo -E
没有保留环境变量(根据我从man sudo
和https://docs.python.org/2/using/cmdline.html的理解,python bla
和sudo -E python bla
之间应该没有区别)
我为什么会得到这个错误呢?
详细情况验证:
$ 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: -
我没有从一个相似但没有答案的问题中得到任何启发,那个问题是为什么PYTHONPATH被忽略?
编辑 1:在考虑了如何为我的Linux系统下的所有人设置环境变量?以及echo ...
并不是一个很好的方法来确保环境变量是否设置后,我在以下位置添加了:
/etc/profile
/etc/profile.d/python_py.sh
/root/.bashrc
/home/richter/.bashrc
现在PYTHONPATH
在sudo -i
提示符下的env
中可用,但在sudo env | grep PYTHONPATH
中不可用。sudo python test.py
仍然因为同样的错误而失败,也就是说我的问题依然存在。
另外,export PYTHONPATH="/home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib" && sudo -E python test.py
也因为同样的错误而失败。
2 个回答
可能是因为你在用的环境(root用户的环境)没有设置PYTHONPATH
这个变量吧?
sudo echo $PYTHONPATH
对于这个命令,我觉得在sudo
执行之前,命令行的替换机制就已经处理过了,所以你实际上只是写了
sudo echo /home/richter/scripts/python:/home/richter/scripts/python/installsystem:/home/richter/scripts/python/lib
这和写
echo $PYTHONPATH
是没什么区别的。
我能理解你可能在考虑使用sudo -E
(不过在你的例子里我没有看到具体的输出)——我个人对sudo -E
没有太多经验。
你可以试试
sudo 'echo $PYTHONPATH'
在这里,单引号可以阻止命令行的替换,同时
sudo -E 'echo $PYTHONPATH'
也要考虑到使用sudo -E
时,可能又会遇到命令行替换的问题……
//这些建议都是我随便想的,实际情况可能会有所不同!
你需要把你的 PYTHONPATH
环境变量添加到 sudoers 的 env_keep
中。
运行以下命令:
sudo visudo
(这个命令会安全地打开 /etc/sudoers
文件)。
在文件中添加这一行:
Defaults env_keep += "PYTHONPATH"
。
然后输入 :wq
,这样就能在使用 sudo
时保留 PYTHONPATH
变量了。