简体   繁体   English

Python + CGI脚本无法访问环境变量

[英]Python + CGI script cannot access environment variables

I'm coding a webservice on python that uses an Oracle database. 我正在编写一个使用Oracle数据库的python上的web服务。 I have cx_Oracle installed and working but I'm having some problems when I run my python code as CGI using Apache. 我已经安装并运行了cx_Oracle但是当我使用Apache将我的python代码作为CGI运行时,我遇到了一些问题。

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. 但是当我以CGI运行它时,我在apache错误日志中得到了“cx_Oracle.InterfaceError:无法获取Oracle环境句柄”。

I searched the Net and everybody says that I have to set the ORACLE_HOME and LD_LIBRARY_PATH environment variables. 我搜索了网络,每个人都说我必须设置ORACLE_HOMELD_LIBRARY_PATH环境变量。 Somehow the CGI script cannot access this environment variables even when I define them using os.putenv as you can see at the code. 不知何故,CGI脚本无法访问此环境变量,即使我使用os.putenv定义它们,您可以在代码中看到。

What I'm I doing wrong? 我做错了什么? Thanks! 谢谢!

This is working for me: 这对我有用:

os.putenv('ORACLE_HOME', '/oracle/client/v10.2.0.3-64bit')
os.putenv('LD_LIBRARY_PATH', '/oracle/client/v10.2.0.3-64bit/lib')
os.environ['ORACLE_HOME'] = '/oracle/client/v10.2.0.3-64bit'
os.environ['LD_LIBRARY_PATH'] = '/oracle/client/v10.2.0.3-64bit/lib'

Mind that first putenv , then update environ . 记住第一个putenv ,然后更新environ

You need this: 你需要这个:

os.environ['ORACLE_HOME'] = '/oracledb/10.2.0/'
os.environ['LD_LIBRARY_PATH'] = '/oracledb/10.2.0/lib'

instead of using os.putenv() because os.putenv() doesn't update os.environ , which cx_Oracle is presumably looking at. 而不是使用os.putenv()因为os.putenv()不更新os.environcx_Oracle可能正在查看。

Documentation: Miscellaneous operating system interfaces says: "Note: Calling putenv() directly does not change os.environ, so it's better to modify os.environ." 文档: 其他操作系统接口说: “注意:直接调用putenv()不会改变os.environ,所以最好修改os.environ。”

Don't forget adding env module for apache: 不要忘记为apache添加env模块:

a2enmod env

in .htaccess or apache configuration: 在.htaccess或apache配置中:

SetEnv LD_LIBRARY_PATH /oracle_lib_path

in /etc/apache2/envvars doesn't work 在/ etc / apache2 / envvars中不起作用

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. 以下是通过在您的盒子上安装Oracle Instant Client来说明如何执行此操作的说明。

installing Oracle Instantclient on Linux without setting environment variables? 在Linux上安装Oracle Instantclient而不设置环境变量?

From just a short google on the problem, it could be that your problem is related to the the ending / in ORACLE_HOME . 从问题的短篇谷歌来看,可能是你的问题与ORACLE_HOME的结尾/有关。
Try removing it (and using also suggestion from Richie) and see if it works. 尝试删除它(并使用Richie的建议),看看它是否有效。

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. 您可以使用shell脚本来实现CGI,在shell脚本中设置环境变量并从shell脚本中调用python脚本。

Setting environment variables from within python seems to be a tricky thing, especially when you are dealing with how libraries are loaded... 在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. 不知何故,apache使用的用户和组无法访问环境变量。 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. 我通过将apache正在使用的用户和组更改为我确定可以访问此变量的用户来解决问题。

It's strange (and frustrating) that it's so difficult to set this variables using Python. 使用Python设置这些变量非常困难(并且令人沮丧)。

Thanks to everyone that answered my question! 感谢所有回答我问题的人!

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). 答案是环境变量LD_LIBRARY_PATH仅在应用程序启动时进行评估(在本例中为Python解释器)。 When Python has started, it is already too late to mess with this variable; 当Python启动时,弄乱这个变量已经太晚了; and it doesn't matter at all whether you set it using os.environ or os.putenv (but generally the former should be used). 无论你是使用os.environ还是os.putenv设置它都没关系(但通常应该使用前者)。

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. 解决方案是在启动Python脚本的包装器脚本中设置LD_LIBRARY_PATH环境变量,或者使用已设置的环境变量启动Apache。 On OpenSUSE, you can do the latter by setting LD_LIBRARY_PATH in /etc/sysconfig/apache2, for instance. 在OpenSUSE上,您可以通过在/ etc / sysconfig / apache2中设置LD_LIBRARY_PATH来执行后者操作。

By the way, the same problem exists when using mod_wsgi instead of a CGI script. 顺便说一句,使用mod_wsgi而不是CGI脚本时存在同样的问题。 See the section "Unable To Find Python Shared Library" on the mod_wsgi Installation Issues page. 请参阅mod_wsgi“ 安装问题”页面上的“无法找到Python共享库”部分。

Are your statements out of order? 你的陈述是否无序?

#!/usr/bin/python 
import os 
os.putenv('ORACLE_HOME', '/oracledb/10.2.0/') 
os.putenv('LD_LIBRARY_PATH', '/oracledb/10.2.0/lib') 

import cx_Oracle 
import defs as df 

con = cx_Oracle.Connection(df.DB_USER, df.DB_PASS, df.DB_SID) 
print con

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM