【问题标题】:How do I properly log only files changed with PHP shell_exec?如何正确记录使用 PHP shell_exec 更改的文件?
【发布时间】:2020-05-28 07:32:56
【问题描述】:

我创建了一个脚本,它将更改的文件从开发站点复制到运行良好的实时站点。

我现在正在尝试记录哪些文件已更改,然后将该列表添加到跟踪更改的数据库表中。

我使用shell_exec 为副本运行rsync,然后尝试修剪输出并添加\n 进行格式化。

输出类似于“发送增量文件列表 portalMaint.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 个的文件。

谢谢。

【问题讨论】:

  • 请张贴未格式化的输出
  • 它在帖子中列出:“发送增量文件列表portalMaint.php发送27,659字节接收81字节55,480.00字节/秒总大小为101,582,367加速为3,661.95”每个空格都有一个换行符。跨度>

标签: php mariadb output shell-exec


【解决方案1】:

如果您的未格式化输出具有相同的模式:

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';
}

【讨论】:

  • 我应该提到,如果有多个文件,它会输出如下:发送增量文件列表 file1.php file2.php file3.php sent ...
  • 我已经尝试了你的建议。它在使用字符串作为 shell 输出的在线 php 测试站点中进行测试时工作。它在我的脚本中不起作用。结果与原始问题相同,空白。我可以很好地回显 shell 输出,但尝试对其进行格式化和处理是行不通的。 shell 输出与常规字符串有什么不同吗?快把我的头发拉出来!
【解决方案2】:

找到答案了!

事实证明,尽管 shell 输出回显为一行,但它掩盖了换行符。因此,在格式化输出时,正则表达式不匹配。

我所做的是将 shell 输出发送到一个我可以看到它是换行的文件。

所以我获取了 shell 输出变量 $filesCopied 并使用 \R 作为模式通过 preg_replace() 运行它。我在这里找到了:Replace multiple newlines, tabs, and spaces

感谢@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);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多