为什么PYTHONPATH中的模块无法找到,尽管包含目录在PYTHONPATH中且文件存在?

13 投票
2 回答
29231 浏览
提问于 2025-04-18 17:48

我遇到了以下情况(通过下面的命令验证):

  • 在目录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.pathHello World!)。而sudo -E python ~/test.py也失败了,错误信息和之前一样。我不明白:

  • 为什么模块不可用,尽管在sudo echo的输出中可以看到PYTHONPATH变量
  • 为什么sudo -E没有保留环境变量(根据我从man sudohttps://docs.python.org/2/using/cmdline.html的理解,python blasudo -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

现在PYTHONPATHsudo -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 个回答

1

可能是因为你在用的环境(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时,可能又会遇到命令行替换的问题……

//这些建议都是我随便想的,实际情况可能会有所不同!

9

你需要把你的 PYTHONPATH 环境变量添加到 sudoers 的 env_keep 中。

运行以下命令:
sudo visudo (这个命令会安全地打开 /etc/sudoers 文件)。

在文件中添加这一行:
Defaults env_keep += "PYTHONPATH"

然后输入 :wq,这样就能在使用 sudo 时保留 PYTHONPATH 变量了。

撰写回答