Функция системного вызова 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);