Функция системного вызова PHP не правильно экспортирует переменные
Я использую диспетчер задач для очереди некоторых задач кодирования видео (см. Http://manpages.ubuntu.com/manpages/artful/en/man1/tsp.1.html и http://vicerveza.homeunix.net/~ viric/soft/ts/)
Чтобы выбрать конкретную очередь (вместо очереди по умолчанию для каждого пользователя), двоичный файл требует, чтобы вы установили переменную среды, указывающую на сокет. В моем случае: TS_SOCKET=/tmp/reencode.socket
. Затем запуск tsp
показывает статус этой конкретной очереди.
Эта команда работает в терминале, так как любой пользователь: export TS_SOCKET=/tmp/reencode.socket; tsp
export TS_SOCKET=/tmp/reencode.socket; tsp
Я хочу создать веб-службу состояния, отображающую этот статус. Однако, используя php на apache2, вызов сценария bash с exec()
с той же точной командой не работает. Также не putenv('TS_SOCKET=/tmp/reencode.socket'); echo exec('tsp');
putenv('TS_SOCKET=/tmp/reencode.socket'); echo exec('tsp');
Я alse попробовал echo 'export TS_SOCKET=/tmp/reencode.socket; tsp'
echo 'export TS_SOCKET=/tmp/reencode.socket; tsp'
Запуск passthru('whoami')
на сервере показывает, что он работает как пользователь www-root
, пользователь сервера Apache. Если я войду в качестве этого пользователя и запустим команду, он будет работать нормально, как ожидалось.
Интересно, что если я запустил php-интерактивную оболочку (php -a
), я могу сделать любой из вышеуказанных PHP-кодов, и он работает просто отлично, так что это похоже на некоторое взаимодействие с apache.
Все это работает на Ubuntu 17.10 с PHP 7.1.11 на Apache 2.4.27
Ответы
Ответ 1
Оказывается, проблема заключается не в настройке переменной окружения, а в доступе к соке. Поскольку apache работает через systemd, он имеет изолированный /tmp
(см. Https://unix.stackexchange.com/questions/345122/why-php-can-not-see-tmp-files), который не совпадает с /tmp
где я помещал сокет. Перемещение местоположения заставило все работать отлично!
Ответ 2
Hm, этот простой тестовый пример, похоже, работает через apache + mod_php (7.0)
<?php
header('content-type: text/plain; charset=utf-8');
$out = [];
exec('SOME_VAR=FOO && echo $SOME_VAR', $out);
// works too: exec('export SOME_VAR=FOO && echo $SOME_VAR', $out);
var_dump($out);
выход:
array(1) {
[0]=>
string(3) "FOO"
}
В вашем случае это будет
<?php
header('content-type: text/plain; charset=utf-8');
$out = [];
exec('TS_SOCKET=/tmp/reencode.socket && tsp', $out);
// also try: exec('export TS_SOCKET=/tmp/reencode.socket && tsp', $out);
var_dump($out);