在执行bash脚本时使用Laravel 5.3显示实时日志

时间:2016-12-09 18:29:59

标签: php ajax bash laravel-5

我有一个bash脚本,它在laravel Controller的一个函数中执行,我想在脚本执行时从内部输出回声。我试过这种方式,但它不起作用,它在脚本执行后显示了所有内容。

这是控制器

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use File;
use Process;
use ProcessFailedException;

class DeployController extends Controller
{
    //
    public function execute_bash(command)
    {
        flush();
        $fp = popen(command, "r");
        while(!feof($fp))
        {
            // send the current file part to the browser
            print fread($fp, 1024);
            // flush the content to the browser
            flush();
        }
        fclose($fp);

    }

我用ajax

做到了
$.ajax({
        data:  parameters,
        url:   '/executeBash',
        type:  'get',
        beforeSend: function(){
            console.log("executing...");
        },
        success:  function(response){
            console.log("success: %O", response);
        },
        error:  function(response){
            console.log("error: %O", response);
        }
    });

这是我在ajax函数调用的web.php Laravel路由文件中的Route语句

Route::get('/executeBash', 'DeployController@execute_bash');
execute_bash函数中的

命令参数是.sh脚本的路径,里面做了一些东西,对于它做的任何事情,它打印带有echo的输出。

现在,.sh脚本正在执行,但完成后会显示所有输出(echo)

我如何实现我想要的誓言?谢谢!

1 个答案:

答案 0 :(得分:1)

好的,我通过以下方式实现了XHR方法:

这是我新的ajax函数(XHR方法)

function executeBash(){

    if (!window.XMLHttpRequest){
        alert("Your browser does not support the native XMLHttpRequest object.");
        return;
    }
    try{
        var xhr = new XMLHttpRequest();
        xhr.previous_text = '';

        xhr.onerror = function() {
            alert("[XHR] Fatal Error.");
        };
        xhr.onreadystatechange = function() {
            try{
                if (xhr.readyState == 4){
                    //alert('[XHR] Done')
                    document.getElementById("timeline").innerHTML += 'Done' + '';
                }
                else if (xhr.readyState > 2){
                    console.warn(xhr.responseText);
                    var new_response = xhr.responseText.substring(xhr.previous_text.length);
                    document.getElementById("timeline").innerHTML += new_response + '';
                    xhr.previous_text = xhr.responseText;
                }
            }
            catch (e){
                alert("[XHR STATECHANGE] Exception: " + e);
            }
        };
        xhr.open("GET", "/executeBash", true);
        xhr.send();
    }
    catch (e){
        alert("[XHR REQUEST] Exception: " + e);
    }

}

这是我的Laravel控制器中的新功能

public function execute_bash(command)
    {
        header("Connection: Keep-alive");

        $fp = popen(command, "r");
        while($b = fgets($fp, 2048)) {
            echo $b."<br>";
            flush();
        }

        pclose($fp);
    }

效果很好!

我通过阅读这篇文章来找到解决方案

http://stratosprovatopoulos.com/web-development/php/ajax-progress-php-script-without-polling/

这个答案

http://www.webhostingtalk.com/showthread.php?t=579738&p=4333537#post4333537

我希望它有所帮助!