Скрипт Python + CGI не может получить доступ к переменным среды
Вопрос
Я кодирую веб-сервис на python, который использует базу данных Oracle.У меня установлен и работает cx_Oracle, но у меня возникают некоторые проблемы, когда я запускаю свой код python как CGI с использованием Apache.
Например, следующий код отлично работает в командной строке:
#!/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, я получаю "cx_Oracle.Ошибка интерфейса:Не удалось получить дескриптор среды Oracle" в журнале ошибок apache.
Я поискал в Сети, и все говорят, что я должен установить ORACLE_HOME
и LD_LIBRARY_PATH
переменные среды.Каким-то образом CGI-скрипт не может получить доступ к этим переменным среды, даже когда я определяю их с помощью os.putenv
как вы можете видеть в коде.
Что Я делаю не так?Спасибо!
Решение 7
Мне удалось решить эту проблему.
Каким-то образом пользователь и группа, которые использовал apache, не имели доступа к переменным среды.Я решил проблему, сменив пользователя и группу, которые использовал apache, на пользователя, у которого, я был уверен, будет доступ к этим переменным.
Странно (и неприятно), что так сложно установить эти переменные с помощью Python.
Спасибо всем, кто ответил на мой вопрос!
Другие советы
У меня это работает:
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
.
Тебе это нужно:
os.environ['ORACLE_HOME'] = '/oracledb/10.2.0/'
os.environ['LD_LIBRARY_PATH'] = '/oracledb/10.2.0/lib'
вместо того, чтобы использовать os.putenv()
потому что os.putenv()
не обновляется os.environ
, который cx_Oracle
предположительно, смотрит на.
Документация: Различные интерфейсы операционной системы говорит: "Примечание:Прямой вызов putenv() не изменяет os.environ , поэтому лучше изменить os.environ."
Не забудьте добавить env модуль для apache:
a2enmod env
в конфигурации .htaccess или apache:
SetEnv LD_LIBRARY_PATH /oracle_lib_path
в /etc/apache2/envvars не работает
Вы можете полностью устранить проблему, если избавитесь от необходимости устанавливать переменные среды.Вот примечание о том, как это сделать, установив Oracle Instant Client на свой компьютер.
установка Oracle Instantclient в Linux без установки переменных окружения?
Всего лишь из короткого Google что касается проблемы, то, возможно, ваша проблема связана с концовкой /
в ORACLE_HOME
.
Попробуйте удалить его (а также использовать предложение Ричи) и посмотрите, сработает ли это.
Вы могли бы использовать сценарий оболочки для реализации CGI, установить переменные среды в сценарии оболочки и вызвать скрипт python из сценария оболочки.
Настройка переменных окружения из python кажется сложной задачей, особенно когда вы имеете дело с тем, как загружаются библиотеки...
Собственно, вопрос, почему код спрашивающего не сработал, еще не получил ответа.
Ответ заключается в том, что переменная окружения LD_LIBRARY_PATH вычисляется только при запуске приложения (в данном случае интерпретатора Python).Когда Python запущен, уже слишком поздно возиться с этой переменной;и совершенно не имеет значения, устанавливаете ли вы его с помощью os.environ или os.putenv (но, как правило, следует использовать первое).
Решение состоит в том, чтобы установить переменную окружения LD_LIBRARY_PATH в скрипте-оболочке, который запускает скрипт Python, или запустить Apache с уже установленной этой переменной окружения.В openSUSE вы можете сделать последнее, установив LD_LIBRARY_PATH, например, в /etc/sysconfig/apache2 .
Кстати, такая же проблема существует и при использовании mod_wsgi вместо CGI-скрипта.Смотрите раздел "Не удалось найти разделяемую библиотеку Python" в mod_wsgi Проблемы с установкой Страница.
Ваши заявления не соответствуют действительности?
#!/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