Как выполнить оболочку script в PHP?
У меня есть script в /var/www/myscript.sh, который создает папки и запускает команду svn update
для моих проектов. Мне нужно выполнить этот script, вызвав его в PHP файле в браузере (то есть Localhost/test.php). Я попытался использовать функции shell_exec()
и exec()
, но это не сработало. Я запустил оболочку script в терминале с помощью su www-data && ./myscript.sh
, и он сработал. Что еще мне не хватает?
<?php
$output = shell_exec("./myscript.sh");
?>
Обновление 5/4/2011:
Я добавил www-data ALL=(ALL) NOPASSWD:ALL
в /etc/sudoers, и он работает, но это очень небезопасно. Есть ли другой способ сделать это?
Ответы
Ответ 1
Несколько возможностей:
- У вас включен безопасный режим. Таким образом, работает только
exec()
, а затем только на исполняемые файлы в safe_mode_exec_dir
-
exec
и shell_exec
отключены в php.ini
- Путь к исполняемому файлу неверен. Если script находится в том же каталоге, что и файл php, попробуйте
exec(dirname(__FILE__) . '/myscript.sh');
Ответ 2
Возможно, вы отключили привилегии exec, большинство пакетов LAMP имеют отключенных. Проверьте ваш php.ini для этой строки:
disable_functions = exec
И удалите записи exec, shell_exec, если они есть.
Удачи!
Ответ 3
Residuum действительно дал правильный ответ на то, как вы должны получить оболочку exec, чтобы найти ваш script, но в отношении безопасности есть несколько точек.
Я бы предположил, что вы не хотите, чтобы ваша оболочка script находилась в вашем веб-корне, поскольку она будет видна всем, у кого есть доступ к вашему серверу.
Я бы порекомендовал перемещать оболочку script за пределы webroot
<?php
$tempFolder = '/tmp';
$webRootFolder = '/var/www';
$scriptName = 'myscript.sh';
$moveCommand = "mv $webRootFolder/$scriptName $tempFolder/$scriptName";
$output = shell_exec($moveCommand);
?>
В отношении:
i добавлены www-данные ALL = (ALL) NOPASSWD: ALL для работы /etc/sudoers
Вы можете изменить это, чтобы покрывать только определенные команды в script, которые требуют sudo. В противном случае, если ни одна из команд в вашем sh script не требует выполнения sudo, вам вообще не нужно это делать.
Попробуйте запустить script в качестве пользователя apache (используйте команду su для переключения на пользователя apache), и если вам не будет предложено отказаться от sudo или отказано в разрешении и т.д., это будет нормально.
т
sudo su apache (or www-data)
cd /var/www
sh ./myscript
Также... что привело меня сюда, я хотел запустить многострочную оболочку script с помощью динамически генерируемых команд. Я хотел, чтобы все мои команды запускались в одной и той же оболочке, что не будет выполняться с помощью нескольких вызовов shell_exec(). Ответ на этот вопрос - сделать так, как Jenkins - создать динамически сгенерированную многострочную команду, поместить ее в переменную, сохранить ее в файл в папке temp, выполнить этот файл (используя shell_exec in() php, поскольку Jenkins Java), затем делать то, что вы хотите с выходом, и удалять временный файл
... voila
Ответ 4
Если у вас небольшой script, который вам нужно запустить (мне просто нужно было скопировать файл), мне было намного проще вызвать команды на PHP скрипт, вызвав
exec("sudo cp /tmp/testfile1 /var/www/html/testfile2");
и включение такой транзакции путем редактирования (или, скорее, добавления) разрешающей строки для sudoers путем первого вызова sudo visudo
и добавления следующей строки к самому ее концу
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/testfile1 /var/www/html/testfile2
Все, что я хотел сделать, это скопировать файл, и у меня возникли проблемы с этим из-за проблемы с корневым паролем, и, как вы уже сказали, я НЕ хотел подвергать систему отсутствию пароля для всех корневых транзакций.