Why is sys.path initialized differently during startup than when run from bash, for Python embedded in Apache
I am using Python embedded in Apache using modwsgi, and I am finding that the sys.path does not get initialized correctly when Apache is started from the rc2.d startup folder than when run from the shell.
The versions:
Ubuntu Lucid 10.04 Apache 2.2 Python 2.6 mod_wsgi 3.3Firstly, I am testing the initialization using this app:
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
When apache2 is started from bash, via 'sudo apache2ctl start', or 'sudo /etc/init.d/apache2 start', it initializes correctly, and the app above shows:
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/l开发者_如何转开发ocal/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin'
When apache2 is started from /etc/rc2.d during boot, it does not initialize correctly, and the app shows:
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'
Critical directories are not found, including dist-packages.
I have tried moving the apache script earlier and later in the startup sequence, and gotten uniformly bad results. Loading apache last in the startup gets the dysfunctional sys.path; loading it from the shell, immediately afterward, loads correctly.
The question, again, is why would the sys.path initialize differently run as a startup process than run from the shell?
Follow-up:
site.py is not being run by Python's initialization. Now I am seeing mod_wsgi errors "unable to import 'site' module". The errors started appearing after providing a WSGIPythonPath value in Apach2.conf, though the sys.path symptoms have been there all along.
There is something about the combination of chrooting Apache and starting from rc#.d scripts that is breaking Python's site.py loading.
Launching Apache from the shell, via sudo, or sudo -i, from a brand new account, works fine.
You're running as a different user. Bash (and your other login scripts) set some of your path variables when you run as your standard user that may not get set when running as the apache user on startup.
Apache is initializing correctly. You just need to be explicit about which paths you want to include, if you need them.
It's the same reason you often need to be more explicit when running cron jobs.
When you use sudo to become that user, part of your existing environment persist, including your your python path variables. You need to use the -i option with sudo to simulate what happens when the root user initially logs in and runs apache.
http://www.gratisoft.us/sudo/man/1.8.0/sudo.man.html#i_command
精彩评论