【问题标题】:Python + CGI script cannot access environment variablesPython + CGI 脚本无法访问环境变量
【发布时间】:2010-11-07 10:01:25
【问题描述】:

我正在使用 Oracle 数据库的 Python 上编写 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: Unable to acquire Oracle environment handle”。

我在网上搜索,每个人都说我必须设置ORACLE_HOMELD_LIBRARY_PATH 环境变量。不知何故,即使我使用 os.putenv 定义它们,CGI 脚本也无法访问此环境变量,正如您在代码中看到的那样。

我做错了什么?谢谢!

【问题讨论】:

  • 你为什么不用mod_wsgi?

标签: python apache cgi cx-oracle


【解决方案1】:

这对我有用:

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'

注意先putenv,然后更新environ

【讨论】:

    【解决方案2】:

    你需要这个:

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

    而不是使用os.putenv(),因为os.putenv() 不会更新os.environcx_Oracle 可能正在查看它。

    文档:Miscellaneous operating system interfaces 说:“注意:直接调用 putenv() 不会改变 os.environ,所以最好修改 os.environ。”

    【讨论】:

    • 尝试结合这个 eduffy的解决方案?
    • 没有。这是一个非常奇怪的问题。如果我添加 print os.environ 我会在字典中定义 ORACLE_HOME 和 LD_LIBRARY_PATH。这可能是 apache 配置问题吗?
    • 我猜除了这两个环境变量之外还有另一个缺失的部分。 另一个 缺少环境变量,或者可能是权限问题。尝试在 CGI 脚本上使用 setuid 以与命令行测试相同的用户身份运行它(我不建议将其用于生产!但它可能有助于隔离问题)。
    【解决方案3】:

    别忘了为 apache 添加 env 模块:

    a2enmod env
    

    在 .htaccess 或 apache 配置中:

    SetEnv LD_LIBRARY_PATH /oracle_lib_path
    

    在 /etc/apache2/envvars 中不起作用

    【讨论】:

      【解决方案4】:

      如果您不再需要设置环境变量,则可以完全消除该问题。下面是关于如何通过在您的机器上安装 Oracle Instant Client 来执行此操作的说明。

      installing Oracle Instantclient on Linux without setting environment variables?

      【讨论】:

        【解决方案5】:

        我已经设法解决了这个问题。

        不知何故,apache 使用的用户和组无权访问环境变量。我通过将 apache 正在使用的用户和组更改为我确定可以访问此变量的用户来解决问题。

        使用 Python 设置这些变量是如此困难,这很奇怪(也令人沮丧)。

        感谢所有回答我问题的人!

        【讨论】:

          【解决方案6】:

          从问题的简短google 来看,您的问题可能与ORACLE_HOME 中的结尾/ 有关。
          尝试删除它(并使用 Richie 的建议),看看它是否有效。

          【讨论】:

            【解决方案7】:

            您可以使用 shell 脚本来实现 CGI,在 shell 脚本中设置环境变量并从 shell 脚本中调用 python 脚本。

            在 python 中设置环境变量似乎是一件棘手的事情,尤其是在处理库的加载方式时...

            【讨论】:

              【解决方案8】:

              提问者的代码为什么不起作用的实际问题尚未得到解答。

              答案是环境变量 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 Installation Issues 页面上的“无法找到 Python 共享库”部分。

              【讨论】:

                【解决方案9】:

                你的陈述有问题吗?

                #!/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
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-16
                  • 1970-01-01
                  • 2019-12-24
                  • 2023-04-11
                  • 2020-10-18
                  • 2014-02-11
                  相关资源
                  最近更新 更多