импорт python завершается ошибкой при вызове из PHP

У меня возникает загадочная проблема при попытке импортировать модуль в python только тогда, когда скрипт вызывается из php через system или exec.

Из оболочки питона:

import igraph #This works.

если предыдущая строка была в файле, скажем, test_module.py, то:
python test_module.py в bash работает.

В PHP:
exec("python test_module.py",$output,$retval) -> терпит неудачу: $retval = 1.

Однако, если сценарий вместо этого: import math, то это нормально.

Кто-нибудь когда-нибудь имел дело с чем-то подобным?


person Alex Nguyen    schedule 18.12.2009    source источник
comment
добавьте import sys; print sys.path в свой скрипт.   -  person jfs    schedule 18.12.2009
comment
import os, site; print os.environ.get('PYTHONPATH'), site.USER_SITE; help(site) тоже может помочь.   -  person jfs    schedule 18.12.2009
comment
Я не вижу различий в sys.path в моей оболочке или в скрипте, вызываемом из PHP.   -  person Alex Nguyen    schedule 18.12.2009
comment
site.USER_SITE у меня не работает (python2.4). В нем говорится, что объект модуля не имеет атрибута USER_SITE.   -  person Alex Nguyen    schedule 18.12.2009


Ответы (4)


нужно проверить sys.path

посмотрите, в чем разница при вызове в каждом направлении

person cobbal    schedule 18.12.2009
comment
Как прокомментировано выше. Я не вижу различий между sys.path. - person Alex Nguyen; 18.12.2009

Это происходит потому, что вы установили эти пакеты под другим пользователем, возможно, root или кем-то еще.

Как я отладил это, я проверил вывод sys.path для обоих случаев (оболочка и php exec, который по умолчанию имеет пользовательские www-данные), а затем сравнил оба.

Я заметил, что путь '/root/.local/lib/python2.7/site-packages' отсутствует, когда я запускал его из PHP, который содержал именно эти отсутствующие пакеты. Поэтому я просто скопировал содержимое этой папки в '/usr/lib/python2.7/dist-packages/', что решило проблему.

person Inc33    schedule 25.12.2015
comment
копировать пакеты python вручную — плохая идея. Вы должны использовать apt-get для установки пакетов Python в /usr/lib/python2.7/dist-packages/. В противном случае используйте pip для установки пакетов Python (возможно, в virtualenv). Вероятно, вы не хотите запускать pip под пользователем root. - person jfs; 02.01.2016

Находится ли модуль igraph в стандартном пути модуля Python или в том же каталоге, что и ваш отдельный скрипт? Если это так, вполне возможно, что PHP вызывает файл python с другим рабочим каталогом и пытается импортировать данные относительно этого пути, а не пути скрипта.

person Amber    schedule 18.12.2009
comment
В оболочке Python: import igraph; print igraph.__file__ возвращает /usr/lib/python2.4/site-packages/python_igraph-0.5.2-py2.4-linux-x86_64.egg/igraph/__init__.pyc Родительский каталог /usr/lib/python2.4 /site-packages/ находится внутри sys.path при вызове из PHP-скрипта. python_igraph-0.5.2-py2.4-linux-x86_64.egg также находится в sys.path. - person Alex Nguyen; 18.12.2009
comment
Вы пытались получить вывод из команды (либо указав аргумент output для вызова exec(), либо используя вместо этого passthru()), чтобы точно увидеть, какую ошибку выдает python при вызове из php? - person Amber; 18.12.2009
comment
Я пытался это сделать. Похоже, что сообщения об ошибках Python не выводятся, поэтому я понятия не имею, что происходит. Однако он имеет возвращаемое значение 1. - person Alex Nguyen; 18.12.2009
comment
Я перенаправил сообщение об ошибке в файл. Это может помочь моему системному администратору увидеть, какие разрешения мне нужны. Большое спасибо. - person Alex Nguyen; 18.12.2009

Это может быть связано со следующей причиной.

Когда вы импортируете пакет, выполняется поиск в определенных каталогах. Эти каталоги указаны внутри sys.path

Создайте файл Python со следующими строками.

import sys
print(sys.path)
  • Запустите этот файл в оболочке и запишите вывод (список путей к каталогам).
  • Запустите тот же файл на локальном сервере (используя PHP) и сравните результаты.

Путь, отсутствующий в выходных данных PHP, вероятно, содержит пакет. Поэтому добавьте следующие строки в файл python, который вы запускаете на сервере.

import sys
sys.path.append("path-to-the-missing-directory")

ЗАПУСТИТЬ ЕГО.

person Vaishakh nambiar    schedule 20.05.2019