Как правильно регистрировать только файлы, измененные с помощью PHP shell_exec?

Я создал скрипт, который копирует измененные файлы с сайта разработки на работающий сайт, который работает безупречно.

Теперь я пытаюсь зарегистрировать, какие файлы были изменены, а затем добавить этот список в таблицу БД, которая отслеживает изменения.

Я использую shell_exec для запуска rsync для копии, а затем пытаюсь обрезать вывод и добавить \n для форматирования.

Вывод выглядит примерно так: «отправка добавочного списка файлов, portMaint.php отправил 27 659 байт, получил 81 байт, 55 480,00 байт/сек, общий размер — 101 582 367, ускорение — 3 661,95».

Вот код, который у меня есть:

$command = "sudo -S rsync -av ".$exclude." ".$source." ".$dest." --delete 2>&1";

    // --- Issue command and check for errors.
    $exErrors = shell_exec($command);

    if (stripos($exErrors, "error:") !== false || stripos($exErrors, "[sudo]")) {
        $error = "Uh-OH, we have a problem! Don't Panic!";
        $errors = $exErrors;

        include("head.php");
        include("template_".$currentPage.".html");
        include("foot.php");
        exit();     
    }else{
        $filesCopied = $exErrors;
        $filesCopied = substr($filesCopied, 0, strrpos($filesCopied, " sent "));
        $filesCopied = preg_replace("/\s+/", "\n", $filesCopied);
    }

Это не работает. $filesCopied оказывается пустым.

Если я закомментирую $filesCopied = substr($filesCopied, 0, strrpos($filesCopied, " sent "));, я получу весь вывод без форматирования.

Что я делаю неправильно? Мне просто нужны файлы, которые были изменены 1 в строке.

Спасибо.


person Sabyre    schedule 12.02.2020    source источник
comment
пожалуйста, выложите неформатированный вывод   -  person Anggara    schedule 12.02.2020
comment
Это указано в посте: отправка добавочного списка файлов portalMaint.php отправлено 27 659 байт получено 81 байт 55 480,00 байт/сек общий размер 101 582 367 ускорение 3 661,95 Каждому пробелу дается перевод строки.   -  person Sabyre    schedule 12.02.2020


Ответы (2)


Если ваш неформатированный вывод имеет тот же шаблон:

sending incremental file list file1.php sent ...
sending incremental file list file2.php sent ...
sending incremental file list file3.php sent ...

вы можете использовать preg_match_all() для записи имен файлов в массив:

if (preg_match_all('/file list (.*?) sent /', $result, $matches)) {
    $filesCopied = $matches[1];
} else {
    echo 'Pattern does not match';
}
person Anggara    schedule 12.02.2020
comment
Я должен был упомянуть, что если есть несколько файлов, он выводит так: отправка добавочного списка файлов file1.php file2.php file3.php send ... - person Sabyre; 12.02.2020
comment
Я попробовал ваше предложение. Он работает во время тестирования на онлайн-тестовых сайтах php, используя строку в качестве вывода оболочки. Это не работает в моем сценарии. Результаты такие же, как и в исходном вопросе, пусто. Я могу просто повторить вывод оболочки, но попытка отформатировать и обработать его не работает. Есть ли что-то другое в выводе оболочки по сравнению с обычной строкой? Собираюсь вырвать мне волосы! - person Sabyre; 13.02.2020

Нашел ответ!

Как оказалось, хотя вывод оболочки повторялся как одна строка, он маскировал разрывы строк. Поэтому, когда дело дошло до форматирования вывода, регулярное выражение не совпадало.

Что я сделал, так это отправил вывод оболочки в файл, где я мог видеть, что он разрывает строку.

Поэтому я взял выходную переменную оболочки $filesCopied и прогнал ее через preg_replace(), используя \R в качестве шаблона. Я нашел это здесь: Заменить несколько новых строк, вкладок и пробелов

Спасибо @Anggara, так как ваш код был лучше моего для форматирования, и это то, что я использую.

Вот мой окончательный код:

    $command = "sudo -S rsync -av ".$exclude." ".$source." ".$dest." --delete 2>&1";

    // --- Issue command and check for errors.
    $exErrors = shell_exec($command);

    if (stripos($exErrors, "error:") !== false || stripos($exErrors, "[sudo]")) {
        $error = "Uh-OH, we have a problem! Don't Panic!";
        $errors = $exErrors;

        include("head.php");
        include("template_".$currentPage.".html");
        include("foot.php");
        exit();     
    }else{
        // -- Strip invisible line breaks
        $filesCopiedRaw = preg_replace('#\R+#', ' ', $exErrors);
        // -- Strip all but files and folders from string and build an array
        preg_match_all('/file list (.*?) sent /', $filesCopiedRaw, $matches);
        $result = $matches[1];
        // -- Convert array to single string
        $filesCopied = "";
        foreach($result as $file) {
            $filesCopied .= $file." ";
        }
        // -- Replace spaces in string with line breaks
        $filesCopied = preg_replace("/\s+/", "\n", $filesCopied);
    }
person Sabyre    schedule 12.02.2020