代码之家  ›  专栏  ›  技术社区  ›  Jeffrey04 George

popen和文件操作

  •  0
  • Jeffrey04 George  · 技术社区  · 16 年前

    有关 this question

    我的脚本基本上运行良好,但有时它在fread函数调用时停止响应,我似乎找不到失败的原因。

    private function run_lengthy_job($command, $message) {
        for($handle = popen($command, 'r'); !feof($handle); sleep(2)) {
            printf("[%s]\t%s\n", time(), $message);
    
            // log the operation
            exec(sprintf('logger "%s"', 
                escapeshellarg(fread($handle, 1024))));
        }
    
        pclose($handle);
    }
    

    实例命令

    hg clone -v --debug http://some.repository.com/hgwebdir.cgi/some_repo some_repo
    

    目前,它在克隆大型存储库时失败了。同样的问题仍然存在,即使我把fread改成fgets。

    关于我的PHP环境的简要信息,

    PHP 5.2.4-2ubuntu5.6 with Suhosin-Patch 0.9.6.2 (cli) (built: Apr 17 2009 14:29:38) 
    Copyright (c) 1997-2007 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
        with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
    

    在Ubuntu 8.04.2上运行

    编辑:尝试用proc-open代替popen,脚本停留在同一位置。 编辑:用流获取内容替换了fread,但仍然停留在同一个位置…

    1 回复  |  直到 16 年前
        1
  •  0
  •   Jeffrey04 George    16 年前

    我当前的解决方案

    private function run_lengthy_job($command, $message) {
        printf("%s\t", $message);
    
        for($handle = popen($command, 'r'),
            stream_set_blocking($handle, FALSE),
            stream_set_timeout($handle, 3); 
            !feof($handle); sleep(1)) {
    
            echo '.';
    
            exec(sprintf('logger "%s"', 
                escapeshellarg(stream_get_contents($handle))));
        }
    
        $exit_status = pclose($handle);
    
        if(pcntl_wifexited($exit_status) 
            && pcntl_wexitstatus($exit_status) == 0) {
            echo "done!\n";
        } else {
            echo "failed!\n";
        }
    }
    

    调用fread时发生的长等待时间可能是因为对$handle的访问被阻塞,popen无法将输出写入它。