PHP: shell_exec(), system(), passthru()


Недавно столкнулся с очередной проблемой зипования/архивирования файлов на удаленном сервере. Было поздно, когда я занялся вопросом создания резервной записи файлов сайта. Просто через CyberDuck гонять файлы долго, и не всегда надежно, т.е. нет гарантии, что файлы все перепишуться, что подключение к интернету не подвиснет или ещё что-нибудь не случится. Поэтому решил использовать собственный урок с собственного блога: Работа с ZIP средствами PHP.
Как я и говорил, было поздно уже, потому сил после рабочего дня осталось не много, но интерес возбудился, так сказать :) .
Вот я и попробовал с помощью немного изменённго собственного примера заархивировать все файлы на серваке и скачать весь сайт ОДНИМ файлом. Получился такой php-скриптик:

< ?php
$folder = '../web'; //архивируем всю папку на уровень выше
$zip_file = 'archive.zip';
$zip = new ZipArchive;
$handle = opendir($folder); //открываем нужную папку и создаем ресурс для работы с внутренностями папки
if($res = $zip->open($zip_file, ZipArchive::CREATE) !== TRUE){
  exit('Не удалось открыть');
}
while(false ! ===($file = readdir($handle))){
$zip->addFile($file);//считываем все файлы в папке и добавляем их по одному в указанный архив
echo "$file".\n;
}
closedir($handle); //закрываем ресурс открытой папки
$zip->close(); //закрываем работу с zip архивом
?>

Вот как-то так… Проблема только в том, что такой скрипт будет работать только с файлами в папке, а вложенные папки будут игнорироваться… Чтобы добавлялись подпапки, нужно добавлять дополнительную проверку каждого файла, но в итоге, архив будет состоять просто из файлов, без папок, т.к. скрипт будет добавлять папки.
Вот, потихоньку подходим к тематике поста. Наткнулся на форуме stackoverflow на пост именно по этой теме, и там я и вспомнил, что когда-то, когда я ещё читал книжки, я изучал работу команды exec(). Эта функция выполняет команды сторонник программ-оболочек, т.е. при использовании php-обработчика на UNIX-сервере, через эту команду можно выполнять команды терминала!!! А с помощью команд терминала намного проще заархивировать как файлы, так и папки всего ОДНОЙ строчкой:

tar -czf backup.tar.gz ../web

Тут стоит немного внести ясности, что я не владею ни доменом infoniac.ru ни площадкой, на которой он хостится, поэтому у меня нет доступа к управлению ни того, ни другого. Поэтому я и не могу просто взять, открыть терминал на хостинге и набрать команду. У меня только ФТП доступ, поэтому приходится как-то выкручиваться.
Вот, в общем, и наткнулся на функции типа shell_exec();, которые способны выполнять команды терминала через среду PHP. Таких команд много и методов работы с ними тоже много. У каждой свои особенности выполнения и использования, но результат примерно одинаковый: выполняются команды оболочки веб-сервера (по крайней мере, в UNIX-системах это работает).
Я сделал тестовый файл на сервере, который показывает, как некоторые из этих команд работают, чтобы можно убедиться в работоспособности этих функций. Вот код файла:

< ?php
echo "<strong>system(\"ls\"):<br />";
echo "&lt;pre>".system('ls')." &lt;/pre>";
echo "<br /><strong>passthru(\"ls\"):</strong><br />";
echo "&lt;pre>".passthru('ls')."&lt;/pre>";
echo "<br /><strong>echo shell_exec(\"ls\"):</strong><br />";
echo "&lt;pre>".shell_exec('ls')."&lt;/pre>";
echo "<br /><strong>echo exec(\"ls\"):</strong><br />";
echo "&lt;pre>".exec('ls')."&lt;/pre>\r\n
?>

Что-то вордпресс и плагин WP-Syntax не способны правильно обработать теги <pre> в коде РНР, который я привожу в пример, потому, публикую как есть.

, , , ,

  1. #1 by Андрей on 13.01.2012 - 3:17 am

    Круто, узнал для себя о запуска команд терминала через функцию систем. А вот екзец как то не заработали, ну да и система хватит, спасибо

(никто не узнает)

Код на картинке: