У меня есть сценарий в /var/www/myscript.sh, который создает папки и запускает команду svn update
для моих проектов. Мне нужно выполнить этот скрипт, вызвав его в PHP-файле в браузере (то есть Localhost / test.php ). Я попытался использовать функции shell_exec()
и exec()
но они не сработали. Я запустил свой сценарий оболочки в терминале с помощью su www-data && ./myscript.sh
и он сработал. Что еще мне не хватает?
<?php $output = shell_exec("./myscript.sh"); ?>
Я добавил www-data ALL=(ALL) NOPASSWD:ALL
в / etc / sudoers, и он работает, но это очень небезопасно. Есть ли другой способ сделать это?
Несколько возможностей:
exec()
, а затем только в исполняемых файлах safe_mode_exec_dir
exec
и shell_exec
отключены в php.ini 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.