蟒蛇 + CGI脚本无法访问环境变量
我正在 python 上编写一个使用 Oracle 数据库的 Web 服务。 我已经安装并运行了 cx_Oracle,但是当我使用 Apache 将 python 代码作为 CGI 运行时遇到了一些问题。
例如,以下代码在命令行中运行得很好:
#!/usr/bin/python
import os
import cx_Oracle
import defs as df
os.putenv('ORACLE_HOME', '/oracledb/10.2.0/')
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib')
con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID)
print con
但是当我将其作为 CGI 运行时,我在 apache 错误日志中收到“cx_Oracle.InterfaceError:无法获取 Oracle 环境句柄”。
我搜索了网络,每个人都说我必须设置 ORACLE_HOME 和 LD_LIBRARY_PATH 环境变量。 不知何故,即使我使用 os.putenv 定义这些环境变量,CGI 脚本也无法访问它们,正如您在代码中看到的那样。
我做错了什么? 谢谢!
I'm coding a webservice on python that uses an Oracle database. I have cx_Oracle installed and working but I'm having some problems when I run my python code as CGI using Apache.
For example the following code works perfectly at the command line:
#!/usr/bin/python
import os
import cx_Oracle
import defs as df
os.putenv('ORACLE_HOME', '/oracledb/10.2.0/')
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib')
con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID)
print con
But when I run it as CGI I get a "cx_Oracle.InterfaceError: Unable to acquire Oracle environment handle" at the apache error log.
I searched the Net and everybody says that I have to set the ORACLE_HOME
and LD_LIBRARY_PATH
environment variables. Somehow the CGI script cannot access this environment variables even when I define them using os.putenv
as you can see at the code.
What I'm I doing wrong? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这对我有用:
请注意,首先
putenv
,然后更新environ
。This is working for me:
Mind that first
putenv
, then updateenviron
.您需要这个:
而不是使用
os.putenv()
因为os.putenv()
不会更新os.environ
,这cx_Oracle
大概正在查看。文档:其他操作系统接口说:“注意:调用 putenv()直接不会改变os.environ,所以最好修改os.environ。”
You need this:
instead of using
os.putenv()
becauseos.putenv()
doesn't updateos.environ
, whichcx_Oracle
is presumably looking at.Documentation: Miscellaneous operating system interfaces says: "Note: Calling putenv() directly does not change os.environ, so it’s better to modify os.environ."
不要忘记为 apache 添加 env 模块:
在 .htaccess 或 apache 配置中:
在 /etc/apache2/envvars 中不起作用
Don't forget adding env module for apache:
in .htaccess or apache configuration:
in /etc/apache2/envvars doesn't work
如果无需设置环境变量,则可以完全消除该问题。 以下是有关如何通过在您的机器上安装 Oracle Instant Client 来执行此操作的说明。
在 Linux 上安装 Oracle Instantclient 而不设置环境变量?
You can eliminate the problem altogether if you eliminate the need to set the environment variables. Here's a note on how to do this by installing the Oracle Instant Client on your box.
installing Oracle Instantclient on Linux without setting environment variables?
我已经成功解决了这个问题。
不知何故,apache 使用的用户和组无权访问环境变量。 我通过将 apache 使用的用户和组更改为我确定有权访问此变量的用户解决了该问题。
奇怪(并且令人沮丧)的是,使用 Python 设置这些变量是如此困难。
感谢所有回答我问题的人!
I've managed to solve the problem.
Somehow the user and group that apache was using didn't have access to the environment variables. I solved the problem by changing the user and group that apache was using to a user that I was certain to have access to this variables.
It's strange (and frustrating) that it's so difficult to set this variables using Python.
Thanks to everyone that answered my question!
来自简短的 google 解决这个问题,您的问题可能与
ORACLE_HOME
中的结尾/
有关。尝试删除它(并使用里奇的建议)并看看它是否有效。
From just a short google on the problem, it could be that your problem is related to the the ending
/
inORACLE_HOME
.Try removing it (and using also suggestion from Richie) and see if it works.
您可以使用 shell 脚本来实现 CGI,在 shell 脚本中设置环境变量并从 shell 脚本中调用 python 脚本。
从 python 中设置环境变量似乎是一件棘手的事情,特别是当你处理库的加载方式时......
You could use a shell script to implement the CGI, set the environment variables in the shell script and call the python script from the shell script.
Setting environment variables from within python seems to be a tricky thing, especially when you are dealing with how libraries are loaded...
为什么提问者的代码不起作用的实际问题尚未得到解答。
答案是环境变量 LD_LIBRARY_PATH 仅在应用程序启动时(在本例中为 Python 解释器)进行评估。 当Python启动后,再去修改这个变量就已经太晚了; 使用 os.environ 还是 os.putenv 设置它并不重要(但通常应该使用前者)。
解决方案是在启动 Python 脚本的包装脚本中设置 LD_LIBRARY_PATH 环境变量,或者在已设置该环境变量的情况下启动 Apache。 例如,在 OpenSUSE 上,您可以通过在 /etc/sysconfig/apache2 中设置 LD_LIBRARY_PATH 来执行后者。
顺便说一下,使用 mod_wsgi 而不是 CGI 脚本时也存在同样的问题。 请参阅 mod_wsgi 安装问题页面上的“无法查找 Python 共享库”部分。
The actual question why the questioner's code did not work has not yet been answered.
The answer is that the environment variable LD_LIBRARY_PATH is only evaluated when an application is started (in this case the Python interpreter). When Python has started, it is already too late to mess with this variable; and it doesn't matter at all whether you set it using os.environ or os.putenv (but generally the former should be used).
The solution is to set the LD_LIBRARY_PATH environment variable in a wrapper script that starts the Python script, or to start Apache with that environment variable already set. On OpenSUSE, you can do the latter by setting LD_LIBRARY_PATH in /etc/sysconfig/apache2, for instance.
By the way, the same problem exists when using mod_wsgi instead of a CGI script. See the section "Unable To Find Python Shared Library" on the mod_wsgi Installation Issues page.
你的说法有问题吗?
Are your statements out of order?