在PHP

时间:2019-06-02 13:57:13

标签: php linux git console exec

我一直试图用PHP克隆存储库,为什么输出只显示给我

cloning into project-name吗? 而不给我显示下一个消息

远程:枚举对象

远程:计数对象

接收对象19%(591/3095),5.06 MiB | 1024.00 KiB / s

git SS

这是我执行实时命令的功能

ob_implicit_flush(true);ob_end_flush();

function liveExecuteCommand($cmd)
{

    // while (@ ob_end_flush()); // end all output buffers if any

    $proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');

    $live_output     = "";
    $complete_output = "";

    while (!feof($proc))
    {
        $live_output     = fread($proc, 4096);
        $complete_output = $complete_output . $live_output;
        echo "$live_output";
        // @ flush();
    }

    pclose($proc);

    // get exit status
    preg_match('/[0-9]+$/', $complete_output, $matches);

    // return exit status and intended output
    return array (
                    'exit_status'  => intval($matches[0]),
                    'output'       => str_replace("Exit status : " . $matches[0], '', $complete_output)
                 );
}

然后我调用该函数:

liveExecuteCommand('git clone https://username:password@gitlab.com/example/project.git');

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

您需要使用--progress开关。

git-clone(1)手册页中:

  

默认情况下在标准错误流上报告进度状态   当它连接到终端时,除非指定-q。这个标志   即使没有标准错误流,也强制执行进度状态   定向到终端。

您应该像这样运行git clone

liveExecuteCommand('git clone --progress https://username:password@gitlab.com/example/project.git');

问题是:

  1. 在外壳程序中运行git clone时,您将连接到终端,并且这些缓冲的流可以很好地工作(您可以看到计数器在移动,等等,就像交互式界面一样)
  2. 当您的代码通过PHP运行时,它没有附加到终端上,因此这种输出将是完全垃圾(即:计数器的许多更新行,直到达到100%等)。

您可以使用一些技巧解决此问题。其中之一是安装expect,它也提供unbuffer可以解决此问题。

liveExecuteCommand('unbuffer git clone --progress https://username:password@gitlab.com/example/project.git');

此外,如果要打印到网页上,请检查是否有助于将echo "$live_output"echo nl2br($live_output)包装起来。