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 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面