У нас есть существующий скрипт, который запускается в оболочке busybox, который использует exec для открытия файла с определенным файловым дескриптором, а затем использует этот файловый дескриптор в вызове flock, чтобы предотвратить запуск параллельных экземпляров. Что-то вроде:
exec 200> /var/run/applock
flock 200
Сценарий работает нормально при запуске из командной строки и cron, но при запуске из системного вызова php с веб-сервера происходит сбой exec с кодом ошибки 2, разрешение запрещено. Я создал минимальный пример, который воспроизводит проблему:
test.htm имеет следующий php:
$res = 0;
system("/tmp/testing", $res);
print($res);
Вызываемый сценарий / tmp / (также проверял этот сценарий, используя sudo в системном вызове php, поэтому в этом сценарии я зарегистрировал UID, чтобы убедиться, что он root, но он также не выполнен):
#!/bin/sh
logger $(id)
exec 200> /tmp/lock
logger Done
exit 0
Полномочия на файлы, полные разрешения для всех:
(host:root) /tmp $ ls -la testing lock
-rwxrwxrwx 1 root root 0 Mar 26 13:38 lock
-rwxrwxrwx 1 root root 65 Mar 26 13:32 testing
Результат на веб-странице равен 2, и в / var / log / messages записывается следующее (указывает, что скрипт фактически выполняется):
Mar 26 14:35:36 host user.notice www: uid=11(www) gid=11(www) groups=11(www)
Мы используем PHP 5.5.9, BusyBox 1.21.1, lighttpd 1.4.35 (используя mod_fastcgi для php). В php.ini безопасный режим не включен, и мы не используем disable_functions.
Одно интересное замечание — эти файлы работают, когда я запускаю его из командной строки от имени пользователя www (тот же пользователь, что и lighttpd, работает):
/usr/local/bin/php-cgi -f test.htm
Просто чтобы быть понятным, мы запускаем несколько сценариев с веб-сервера аналогичным образом, которые работают нормально, и рассматриваемый сценарий запускается до тех пор, пока не достигнет «exec 200> / var / run / applock». Любая помощь будет оценена.
Задача ещё не решена.
Других решений пока нет …