对于嵌入Apache中的Python,为什么sys.path在启动期间的初始化与从bash运行时的初始化不同

对于嵌入Apache中的Python,为什么sys.path在启动期间的初始化与从bash运行时的初始化不同,python,apache,mod-wsgi,Python,Apache,Mod Wsgi,我正在使用modwsgi使用Apache中嵌入的Python,并且我发现当Apache从rc2.d启动文件夹启动时,sys.path没有正确初始化,而不是从shell运行时 版本: Ubuntu Lucid 10.04 Apache 2.2 Python 2.6 mod_wsgi 3.3 首先,我正在使用此应用程序测试初始化: import sys import os def application(environ, start_response): status =

我正在使用modwsgi使用Apache中嵌入的Python,并且我发现当Apache从rc2.d启动文件夹启动时,sys.path没有正确初始化,而不是从shell运行时

版本:
Ubuntu Lucid 10.04
Apache 2.2
Python 2.6
mod_wsgi 3.3

首先,我正在使用此应用程序测试初始化:

import sys   
import os   
def application(environ, start_response):   
    status = '200 OK'   
    output = ['version %s\n'%sys.version]   
    output.append('sys.prefix = %s \n' % repr(sys.prefix))   
    output.append('sys.exec_prefix = %s \n' % repr(sys.exec_prefix))  
    output.append('sys.path = %s \n' % repr(sys.path))  
    output.append('env.PYTHONHOME = %s\n' % repr(os.environ.get('PYTHONHOME')))
    output.append('env.PATH = %s\n' % repr(os.environ.get('PATH')))
    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(sum([len(o) for o in output])))]
    start_response(status, response_headers)
    return output
当通过“sudo apache2ctl start”或“sudo/etc/init.d/apache2 start”从bash启动apache2时,它将正确初始化,并且上面的应用程序显示:

version 2.6.5 (r265:79063, Apr 16 2010, 14:15:55) 
[GCC 4.4.3]
sys.prefix = '/usr' 
sys.exec_prefix = '/usr/local' 
sys.path = ['/usr/local/lib/python2.6/dist-packages/WebOb-1.0.7-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/twiddler-0.9.1-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/elementtree-1.2.7_20070827_preview-py2.6.egg', '/usr/local/lib/python2.6/dist-packages/lxml-2.3-py2.6-linux-x86_64.egg', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/local/lib/python2.6/lib-dynload', '/usr/lib/python2.6/dist-packages', '/usr/lib/pymodules/python2.6', '/usr/local/lib/python2.6/dist-packages', '/usr/local/lib/python2.6/dist-packages'] 
env.PYTHONHOME = '/usr:/usr/local'
env.PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin'
当apache2在引导期间从/etc/rc2.d启动时,它无法正确初始化,并且应用程序显示:

version 2.6.5 (r265:79063, Apr 16 2010, 14:15:55) 
[GCC 4.4.3]
sys.prefix = '/usr' 
sys.exec_prefix = '/usr/local' 
sys.path = ['/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/local/lib/python2.6/lib-dynload'] 
env.PYTHONHOME = '/usr:/usr/local'
env.PATH = '/sbin:/usr/sbin:/bin:/usr/bin'
未找到关键目录,包括dist包

我尝试过在启动序列中前后移动apache脚本,结果都很糟糕。在启动过程中加载apache last会得到不正常的sys.path;从壳中加载后,立即正确加载

问题是,为什么sys.path初始化作为启动进程运行与从shell运行不同

后续行动:

Python的初始化没有运行site.py。现在我看到mod_wsgi错误“无法导入‘站点’模块”。在Apach2.conf中提供WSGIPythonPath值后,错误开始出现,尽管sys.path症状一直存在

chrooting Apache和从rc#.d脚本开始的组合打破了Python的site.py加载


从shell通过sudo或sudo-i从一个全新的帐户启动Apache,效果很好。

您正在以不同的用户身份运行。Bash(以及您的其他登录脚本)在您作为标准用户运行时设置了一些path变量,这些变量在启动时作为apache用户运行时可能无法设置

Apache正在正确初始化。如果需要的话,只需明确说明要包含哪些路径

这与运行cron作业时通常需要更加明确的原因相同

当您使用sudo成为该用户时,现有环境的一部分会保留下来,包括python路径变量。您需要在sudo中使用-i选项来模拟root用户最初登录并运行apache时发生的情况


在这两种情况下,
PYTHONPATH
环境变量的值是多少?这听起来像是Ubuntu的问题,而不是Python或httpd的问题。@sarnold没有使用PYTHONPATH env变量。我可以使用它,但它必须很长而且很混乱。为什么您要在一开始就设置PYTHONHOME环境变量,因为您不需要这样做?您还希望避免依赖用户帐户中设置的PYTHONPATH,所以现在不要尝试为Apache设置PYTHONPATH。根据需要使用WSGIPythonPath或python path选项来设置WSGIDaemonProcess,以确定是使用mod_wsgi嵌入式模式还是守护程序模式。在WSGI脚本中设置sys.path。如果您真的需要设置PYTHONHOME(我对此非常怀疑),那么Apache中的指令是WSGIPythonHome。我相信用户在这两种情况下都是root用户。@pduel,这取决于调用
sudo
的方式--
sudo-I
将清除环境,
sudo-s
将仅执行通过
sudoers(5)
中的
env_reset
配置的任何环境清理。因此,标准用户
/home/pduel/.bashrc
-set
PYTHONPATH
将持久存在
sudo-s
环境中,但将从
sudo-i
环境中清除。@sarnold甚至sudo-i似乎也不会清除路径。我在应用程序中添加了一个完整的环境转储,发现成功案例的路径比失败案例的路径更完整;是时候用蟒蛇做实验了。