Как выполнить скрипт оболочки в PHP?

У меня есть сценарий в /var/www/myscript.sh, который создает папки и запускает команду svn update для моих проектов. Мне нужно выполнить этот скрипт, вызвав его в PHP-файле в браузере (то есть Localhost / test.php ). Я попытался использовать функции shell_exec() и exec() но они не сработали. Я запустил свой сценарий оболочки в терминале с помощью su www-data && ./myscript.sh и он сработал. Что еще мне не хватает?

 <?php $output = shell_exec("./myscript.sh"); ?> 

Обновление 5/4/2011:

Я добавил www-data ALL=(ALL) NOPASSWD:ALL в / etc / sudoers, и он работает, но это очень небезопасно. Есть ли другой способ сделать это?

Несколько возможностей:

  • У вас включен безопасный режим. Таким образом, работает только exec() , а затем только в исполняемых файлах safe_mode_exec_dir
  • exec и shell_exec отключены в php.ini
  • Путь к исполняемому файлу неверен. Если скрипт находится в том же каталоге, что и файл php, попробуйте выполнить exec(dirname(__FILE__) . '/myscript.sh');

Возможно, вы отключили привилегии exec, большинство пакетов LAMP имеют отключенные. Проверьте ваш php.ini для этой строки:

 disable_functions = exec 

И удалите записи exec, shell_exec, если они есть.

Удачи!

Residuum действительно дал правильный ответ на то, как вы должны получить оболочку exec, чтобы найти ваш скрипт, но в отношении безопасности есть несколько моментов.

Я бы предположил, что вы не хотите, чтобы ваш сценарий оболочки находился в вашем веб-корне, поскольку он будет виден всем, у кого есть веб-доступ к вашему серверу.

Я бы порекомендовал перемещать скрипт оболочки за пределы веб-сайта

  <?php $tempFolder = '/tmp'; $webRootFolder = '/var/www'; $scriptName = 'myscript.sh'; $moveCommand = "mv $webRootFolder/$scriptName $tempFolder/$scriptName"; $output = shell_exec($moveCommand); ?> 

Что касается:

я добавил www-данные ALL = (ALL) NOPASSWD: ALL для работы / etc / sudoers

Вы можете изменить это, чтобы покрывать только определенные команды в вашем скрипте, которые требуют sudo. В противном случае, если ни одна из команд в вашем sh-скрипте не требует выполнения sudo, вам вообще не нужно это делать.

Попробуйте запустить скрипт в качестве пользователя apache (используйте команду su для переключения на пользователя apache), и если вам не будет предложено отказаться от sudo или отказано в разрешении и т. Д., Все будет в порядке.

то есть:

 sudo su apache (or www-data) cd /var/www sh ./myscript 

Также … что привело меня сюда, так это то, что я хотел запустить сценарий многострочной оболочки, используя динамически генерируемые команды. Я хотел, чтобы все мои команды запускались в одной и той же оболочке, что не будет выполняться с помощью нескольких вызовов shell_exec (). Ответ на этот вопрос – сделать так, как Jenkins – создать динамически сгенерированную многострочную команду, поместить ее в переменную, сохранить ее в файл в папке temp, выполнить этот файл (используя shell_exec in () php, поскольку Jenkins Java), а затем делать то, что вы хотите с выходом, и удалять временный файл

… вуаля

Если у вас небольшой скрипт, который вам нужно запустить (мне просто нужно было скопировать файл), мне было намного проще вызвать команды на скрипте PHP, вызвав

 exec("sudo cp /tmp/testfile1 /var/www/html/testfile2"); 

и позволяя такую ​​транзакцию путем редактирования (или, скорее, добавления) линии разрешений для судоустройств, сначала вызывая sudo visudo и добавляя следующую строку до самого конца

 www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/testfile1 /var/www/html/testfile2 

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