douzhanbai9526 2012-02-27 16:02
浏览 76
已采纳

在php中执行程序 - 显示并返回输出

In php there are several methods to execute a shell command:

  • system()
  • passthru()
  • shell_exec()
  • exec()

First two displays output but doesn't return it. Last two returns output but doesn't display it.

I want to run shell command which require a lot of time but it displays some output so I know it doesn't hang. However at the end I want to process this output in php. If I choose one of first two I won't get output so I will be unable to process it in php. If I run one of the last two I will be able to process output however my program will hang very long time without outputting anything.

Is there a way to run a shell command which will display output immediately and return it?

  • 写回答

2条回答 默认 最新

  • dpwo36915 2012-02-27 16:24
    关注

    Maybe this one will interest you? proc_open() - http://www.php.net/manual/en/function.proc-open.php

    And here is a handy snippet which might work for you (it's copied from the comments on the site I gave you the link to):

    <?php
    /*
     * Execute and display the output in real time (stdout + stderr).
     *
     * Please note this snippet is prepended with an appropriate shebang for the 
     * CLI. You can re-use only the function.
     * 
     * Usage example:
     * chmod u+x proc_open.php
     * ./proc_open.php "ping -c 5 google.fr"; echo RetVal=$?
     */
    define(BUF_SIZ, 1024);        # max buffer size
    define(FD_WRITE, 0);        # stdin
    define(FD_READ, 1);        # stdout
    define(FD_ERR, 2);        # stderr
    
    /*
     * Wrapper for proc_*() functions.
     * The first parameter $cmd is the command line to execute.
     * Return the exit code of the process.
     */
    function proc_exec($cmd)
    {
        $descriptorspec = array(
            0 => array("pipe", "r"),
            1 => array("pipe", "w"),
            2 => array("pipe", "w")
        );
    
        $ptr = proc_open($cmd, $descriptorspec, $pipes, NULL, $_ENV);
        if (!is_resource($ptr))
            return false;
    
        while (($buffer = fgets($pipes[FD_READ], BUF_SIZ)) != NULL 
                || ($errbuf = fgets($pipes[FD_ERR], BUF_SIZ)) != NULL) {
            if (!isset($flag)) {
                $pstatus = proc_get_status($ptr);
                $first_exitcode = $pstatus["exitcode"];
                $flag = true;
            }
            if (strlen($buffer))
                echo $buffer;
            if (strlen($errbuf))
                echo "ERR: " . $errbuf;
        }
    
        foreach ($pipes as $pipe)
            fclose($pipe);
    
        /* Get the expected *exit* code to return the value */
        $pstatus = proc_get_status($ptr);
        if (!strlen($pstatus["exitcode"]) || $pstatus["running"]) {
            /* we can trust the retval of proc_close() */
            if ($pstatus["running"])
                proc_terminate($ptr);
            $ret = proc_close($ptr);
        } else {
            if ((($first_exitcode + 256) % 256) == 255 
                    && (($pstatus["exitcode"] + 256) % 256) != 255)
                $ret = $pstatus["exitcode"];
            elseif (!strlen($first_exitcode))
                $ret = $pstatus["exitcode"];
            elseif ((($first_exitcode + 256) % 256) != 255)
                $ret = $first_exitcode;
            else
                $ret = 0; /* we "deduce" an EXIT_SUCCESS ;) */
            proc_close($ptr);
        }
    
        return ($ret + 256) % 256;
    }
    
    /* __init__ */
    if (isset($argv) && count($argv) > 1 && !empty($argv[1])) {
        if (($ret = proc_exec($argv[1])) === false)
            die("Error: not enough FD or out of memory.
    ");
        elseif ($ret == 127)
            die("Command not found (returned by sh).
    ");
        else
            exit($ret);
    }
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法