Подтвердить что ты не робот

Как выполнить оболочку 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, и он работает, но это очень небезопасно. Есть ли другой способ сделать это?

4b9b3361

Ответ 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

Все, что я хотел сделать, это скопировать файл, и у меня возникли проблемы с этим из-за проблемы с корневым паролем, и, как вы уже сказали, я НЕ хотел подвергать систему отсутствию пароля для всех корневых транзакций.