为什么 django 会忽略一些环境变量,除非我在重新启动时将它们传递给 httpd?
这是我的应用环境:
Redhat 6.0
Apache 2.2
Django 1.3.0
Python 2.6.6
cx_Oracle 5.1
mod_wsgi 3.2
Oracle DBMS 11.2 (on a different machine)
问题: 从 Web 浏览器访问我的 Django 网站失败,因为 cx_Oracle 无法获取 Oracle 句柄。
测试:
- 运行 django-admin.py shell 来查询数据库确实有效(从设置了 ORACLE_HOME 和 LD_LIBRARY_PATH 变量的 bash 会话运行)
- 运行自定义脚本,将 ORACLE_HOME 和 LD_LIBRARY_PATH 添加到 os.environ 并使用 cx_Oracle 连接到数据库,无需使用 django 确实有效(从带有 ORACLE_HOME 的 bash 会话运行,并且LD_LIBRARY_PATH vars set)
- 使用“sudo -u apache”运行相同的自定义脚本不起作用
- 使用“sudo -u env ORACLE_HOME=foo LD_LIBRARY_PATH=foo myscript.py”运行相同的自定义脚本可以
- 修改 django.db.backends.oracle .base.py 这样,在 Database.connect 语句之前,我将 os.environ 打印到文件中,显示我已经ORACLE_HOME 和 LD_LIBRARY_PATH 正确设置
- 在 adhoc django wsgi.py 脚本内的 os.environment 中显式设置 ORACLE_HOME 和 LD_LIBRARY_PATH 不起作用
- 用“sudo env ORACLE_HOME=foo LD_LIBRARY_PATH=foo /etc/init.d/httpd restart”重新启动 httpd 确实有效
我的问题是:为什么测试 7 与测试 2 不同, 5、6?换句话说,为什么我必须将环境变量传递给父 httpd 进程,而不是仅仅在 python/django 脚本中设置它们?
This is my application environment:
Redhat 6.0
Apache 2.2
Django 1.3.0
Python 2.6.6
cx_Oracle 5.1
mod_wsgi 3.2
Oracle DBMS 11.2 (on a different machine)
Issue:
accessing my django website from a web browser fails because cx_Oracle can't acquire Oracle handle.
Tests:
- running django-admin.py shell to query the db DOES WORK (running from a bash session with ORACLE_HOME and LD_LIBRARY_PATH vars set)
- running a custom script that adds ORACLE_HOME and LD_LIBRARY_PATH to os.environ and uses cx_Oracle to connect to DB, without using django DOES WORK (running from a bash session with ORACLE_HOME and LD_LIBRARY_PATH vars set)
- running the same custom script with "sudo -u apache" does NOT work
- running the same custom script with "sudo -u env ORACLE_HOME=foo LD_LIBRARY_PATH=foo myscript.py" DOES WORK
- modifying django.db.backends.oracle.base.py so that, before the Database.connect statement, I have os.environ printed to a file, SHOWS I HAVE ORACLE_HOME AND LD_LIBRARY_PATH CORRECTLY SET
- explicitly setting ORACLE_HOME and LD_LIBRARY_PATH in os.environment inside adhoc django wsgi.py script DOES NOT WORK
- restarting httpd with "sudo env ORACLE_HOME=foo LD_LIBRARY_PATH=foo /etc/init.d/httpd restart" DOES WORK
My question is: why is test 7 different from tests 2, 5, 6? To put it another way, why do I have to pass env vars to parent httpd process instead of just setting them in python/django scripts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
LD_LIBRARY_PATH 必须位于执行进程之前的环境中。进程运行时加载器只会在启动时读取它一次,在进程启动后更改环境值没有任何区别。这就是事情的运作方式。
The LD_LIBRARY_PATH must be in the environment prior to a process being executed. The process runtime loader will only read it once at startup, changing the value of the environment after the process has been started makes no difference. This is just how things work.