Невозможно запустить команду оболочки через php exec, но можно как пользователь оболочки?

Я пытаюсь заставить exiftool работать на моем выделенном сервере. Проблема в том, что PHP exec, похоже, работает иначе, чем когда команда запускается от имени пользователя. Как ни странно, PHP отображается как тот же пользователь, с которым я вхожу в систему, но он не ведет себя так же с системными командами.

Как ни странно, все отлично работает на моем локальном хосте, но не на моем сервере.

Итак, как уже упоминалось, выполнение команд exiftool, зарегистрированных через ssh, нормально.

Но при запуске в сценарии тестирования php (обратите внимание, что я установил exiftool в каждый проверенный каталог, и он работает через ssh), ничего недоступно, хотя он работает как пользователь orangeman ...

И это не удается

Вот обновление, которое я провел в этом весь день:

На оболочке:

-bash-4.1$ which exiftool -a
~/perl5/bin/exiftool
/usr/bin/exiftool
~/perl5/bin/exiftool

В PHP shell_exec('exiftool -a');

/usr/bin/exiftool

И вот на что ссылается этот файл:

lrwxrwxrwx    1 root root          33 May 15 02:10 exiftool -> /home/orangeman/perl5/bin/exiftool

Я также пробовал создавать символические ссылки различного типа, изменяя основную переменную $ PATH через putenv(); в php ... Я действительно в темноте. Работает на локальном хосте, а не на выделенном сервере.


Я обновил это с помощью щедрости - это серьезная проблема в разработке.

Я использую выделенный сервер, и проблема описана выше.


ОБНОВЛЕНИЕ. Согласно предложению @gcb, мне удалось распечатать ошибку, которая возникает, когда функция php exec () запускает системную команду без какого-либо эффекта.

PHP

<?php
exec('exiftool 2>&1', $output, $r);
var_dump($output, $r);
?>

Вывод:

array(2) {
  [0]=>
  string(230) "Can't locate Image/ExifTool.pm in @INC (@INC contains: /bin/lib /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /bin/exiftool line 33."
  [1]=>
  string(59) "BEGIN failed--compilation aborted at /bin/exiftool line 33."
}

ОБНОВЛЕНИЕ

Решение @gcb сработало. Большое Вам спасибо.


person Orangeman555    schedule 14.05.2014    source источник
comment
Находится ли php в chroot? Есть ли у него разрешение на просмотр этих каталогов?   -  person Zoredache    schedule 14.05.2014
comment
'which php' возвращает '/ usr / local / bin / php'. Я не знаком с «chroot», но если это возможно, что можно было бы обойти?   -  person Orangeman555    schedule 14.05.2014
comment
Вы бы поместили нужные вам файлы / программы внутрь chroot. О том, что это такое, см. Запись в Википедии. en.wikipedia.org/wiki/Chroot   -  person Zoredache    schedule 14.05.2014
comment
/usr/bin/exiftool не является каталогом. /usr/bin - это каталог, а /usr/bin/exiftool (если он существует) - это файл.   -  person that other guy    schedule 14.05.2014


Ответы (4)


Итак, у вас сейчас проблема не с php, а с perl. ваш путь включения плохой.

ответьте здесь http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=2217.0

You either have to install the ExifTool libraries in the
standard location (ie. somewhere in the @INC directories
listed in your post), or add the location to the include path,
something like this:

Code:
#!/usr/bin/perl
BEGIN { unshift @INC, "PATH_TO_DIRECTORY_CONTAINING_LIBRARIES" }
use Image::ExifTool;

You should be able to add "Image/ExifTool.pm" to the path you add
to find the ExifTool module.

- Phil

Я все еще думаю, что использование моего предложения № 3 из предыдущего ответа исправит это. Если нет, и вы действительно хотите узнать причину, создайте новый скрипт perl, который просто выводит содержимое @INC, и запускает его через оболочку и через php. вы увидите разницу, тогда вам нужно найти, какой сценарий входа в систему не соблюдается в php, и открыть ошибку в php, если shell_exec не соблюдает его ...

хотя более простое решение вашей проблемы (поскольку не похоже, что вы слишком заинтересованы в объяснениях) - просто установить переменную PERLLIB перед вызовом скрипта.

Итак, просто сделайте:

  1. find / -name ExifTool.pm Это сообщит вам, где установлена ​​библиотека. скажем, это возвращает /example/perl/Image/ExifTool.pm
  2. добавьте PERL5LIB=/example/perl/ к вашему вызову exec ().
  3. exec (PERL5LIB = / example / perl / /var/www/myscript/execscript.sh {$ param}); #и
person gcb    schedule 18.05.2014
comment
... поскольку это не похоже на то, что вы слишком заинтересованы в объяснениях ... не так! Я очень заинтересован. Я занимаюсь этим почти неделю. Это кажется наиболее вероятным ответом. Сейчас осматриваю. Я разархивировал временный каталог и запустил make ... при условии, что он установится правильно. Видимо стандартным способом не установил. Я исследовал это сегодня утром, основываясь на вашем наблюдении. Я совсем не разбираюсь в Perl, поэтому для меня это было медленнее. - person Orangeman555; 19.05.2014
comment
Это было - большое спасибо. Я назначу награду, как только это позволит мне (через 5 часов) - очень признателен. - person Orangeman555; 19.05.2014
comment
@ Orangeman555 спасибо. Что касается обучения, я, честно говоря, не думаю, что вам нужно изучать Perl, чтобы решить эту проблему. если вы хотите улучшить, изучите Linux (структура файловой системы, разрешения файлов, stdout vs stdout, т.е. буферы и потоки, а также о той или иной оболочке, я предлагаю bash) и узнайте о выбранной вами рабочей среде (php, apache, я предполагая) узнайте, где искать журналы ошибок и т. д., в конечном итоге вы увидите, что все происходит по одному шаблону, и это становится легко :) Ура. - person gcb; 19.05.2014

0) вам следует посмотреть журнал ошибок. обычно в / var / log / apache / error

в нем будут сообщения типа «доступ запрещен» или что-то еще.

1) вы явно не получаете достаточно вывода этой команды, чтобы увидеть какую-либо ошибку. поэтому попробуйте запустить его с exiftool 2>&1. это перенаправит stderr на stdout, поэтому на выходе будут появляться ошибки. не уверен, актуально ли это, или php уже это делает. вы также можете использовать passthru вместо exec

2) безопасный режим exec dir

ваш файл может быть вне вашего безопасного режима exec dir. прочтите это:

http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-exec-dir

3) все остальное не удается, запустите команду как оболочку входа в систему, в которой должны быть загружены те же сценарии, что и при входе в систему через ssh. просто замените exec на shell_exec

... я почти уверен, что просмотр журнала ошибок решит вашу загадку.

person gcb    schedule 18.05.2014
comment
Сейчас проверяю ваши предложения. Вернусь к вам - большое спасибо. - person Orangeman555; 18.05.2014
comment
ЗАМЕЧАТЕЛЬНОЕ предложение. Я обновил исходный пост с результатами. Я не знал, как получить журналы ошибок из оболочки, так что это огромный прогресс. Теперь мы видим, что он выдает ошибку, которую мы, очевидно, не получаем при входе в систему через оболочку, так что это показывает? - person Orangeman555; 18.05.2014

Одна из возможностей состоит в том, что в командной строке ваш $PATH был установлен / изменен как вашим $HOME/.bashrc, так и вашим $HOME/.bash_profile, потому что ваша командная строка является оболочкой для входа в систему. Когда PHP вызывается веб-сервером, он запускается как "orangeman" НО только как оболочка, а не как оболочка для входа в систему, поэтому его $PATH может не совпадать , что вы здесь видите. Вы пробовали вставить export PATH="what:you:want:your:PHP:path:to:be" в свой $HOME/.bashrc?

person aqn    schedule 15.05.2014
comment
Я повозился с этим - не уверен, что сделал это правильно. Следует ли это делать с помощью сценария PHP во время его работы или есть постоянный способ установить это для системы? - person Orangeman555; 15.05.2014

Я считаю, что это происходит потому, что у вас есть частная установка perl для вашего пользователя.

По сути, @INC - это массив, который Perl использует для поиска своей библиотеки, и он не содержит пути к вашей установочной библиотеке.

Есть несколько способов изменить @INC, которые вы можете найти по ссылке ниже:

http://perlmaven.com/how-to-change-inc-to-find-perl-modules-in-non-standard-locations

Надеюсь, это поможет.

person Tiago Lopo    schedule 18.05.2014