Почему исполняемый файл не может найти общую библиотеку только при запуске как http-запрос

#php #linux #bash #shell #exec

#php #linux #bash #оболочка #exec

Вопрос:

У меня есть php-файл, в котором есть вызов shell_exec. Функции shell_exec запускают файл .sh.

 #!/bin/bash

filename=$(ls *.jpg -Art | tail -n 1)
codegen_dir=/usr/local/codegen/

cd "$codegen_dir"
out=$(./classifier /var/www/$filename)
echo $out
  

Исполняемый ‘classifier’ существует в codegen_dir и имеет 1 зависимость от разделяемой библиотеки. Скрипт корректно запускается из командной строки. Файл php также корректно запускается из командной строки. однако, когда я запускаю php-файл как http-запрос, я получаю следующее в std_err:

«./classifier: ошибка при загрузке разделяемых библиотек: libreader.so : не удается открыть общий объектный файл: нет такого файла или каталога»

Файл .so находится в том же каталоге, что и исполняемый файл

Мой корневой каталог php-сервера: /var/ www

  • Все файлы в корневом каталоге сервера имеют разрешения:-rwxrwxrwx 1 www-data www-данные
  • Все файлы в ‘codegen_dir’ имеют разрешения: -rwxrwxrwx 1 ubuntu www-data
  • Я могу читать другие файлы в codegen_dir

Комментарии:

1. Можем ли мы получить код ./classifier и в httpd.conf ?

2. Я не вносил никаких изменений в httpd.conf и я не могу поделиться кодом для исполняемого файла. Однако я могу прояснить свой вопрос: это исполняемый файл, который имеет ровно одну зависимость от общей библиотеки (файл.so), если это поможет

3. Загрузчик никогда не проверяет текущий каталог на наличие общих объектов, если на него явно не указано через $LD_LIBRARY_PATH. Смотрите ld.so (8) справочная страница для получения дополнительной информации. Вы можете поместить свою разделяемую библиотеку в одно из стандартных мест, см. /etc /ld.so.conf. Пример: /usr/local/lib/libreader.so

4. повторюсь: я могу запустить скрипт в командной строке, проблема в том, когда я запускаю его из http-запроса. Да, у меня настроен ld.so.conf

Ответ №1:

Общий путь к библиотеке может быть недоступен пользователю apache. Вы можете разрешить программу-классификатор в файле sudoers для apache и использовать sudo для запуска приложения-классификатора от имени пользователя apache

Или сделайте разделяемую библиотеку и ее путь доступными для всех пользователей, изменив ее разрешение

 out=$(sudo ./classifier /var/www/$filename)
  

Попробуйте войти в систему с помощью пользователя apache и запустить приведенный выше скрипт или попробуйте получить доступ к общей библиотеке

 su -s /bin/bash apache
  

Комментарии:

1. Как упоминалось выше, другие файлы в том же каталоге, что и общая библиотека, могут быть прочитаны пользователем apache

2. Попробуйте войти в систему с помощью пользователя apache и запустить приведенный выше скрипт или попробуйте получить доступ к общей библиотеке

3. Я могу корректно запустить скрипт как пользователь apache, но не как http-запрос. Я думаю, это потому, что подпроцесс (запущенный из shell_exec) не имеет доступа к LD_LIBRARY_PATH. Есть ли какой-либо способ обойти это?

4. Попробуйте экспортировать LD_LIBRARY_PATH в начало сценария оболочки

5. экспорт LD_LIBRARY_PATH в верхней части сценария оболочки работает, но есть ли более аккуратный способ сделать это