2011-08-29 74 views
1

背景: 我想写一个使用PHP的shell脚本,将自动签出几个大的SVN回购。我也使用PEAR控制台进度条类来显示结帐的进度(不是完全必要的,但提示我的问题)。获取PHP更新与从命令返回的每一行

问: 是否有一种方式来运行一个循环,将每行输出到标准输入的命令行更新?

如果我做

<?php shell_exec("svn co svn://my.repo.com/repo/trunk"); ?> 

我找回所有的命令在一个巨大的字符串输出。 尝试像

<?php  $bar = new Console_ProgressBar('%fraction% [%bar%] %percent% | %elapsed% :: %estimate%', '=>', ' ', 80, $total); 
    $bar->display(0); 
    stream_set_blocking(STDIN, 0); 
    $output = array(); 
    $return = ''; 
    exec("svn co $svnUrl $folder", $output, $return); 
    while (!isset($return)) 
    { 
     $bar->update(count($output)); 
    } 
    $bar->erase(); ?> 

将显示栏但不更新。

任何解决方案?

更新=================== ====================

这是我想出了基于答案的工作代码(备查):

<?php  
    $bar = new Console_ProgressBar('%fraction% [%bar%] %percent% | %elapsed% :: %estimate%', '=>', ' ', 80, $total); 
    $handle = popen("/usr/bin/svn co $svnUrl $folder", 'r'); 
    $elapsed = 0; 
    $bar->display($elapsed); 

    while ($line = fgets($handle)) 
    { 
     $elapsed++; 
     $bar->update($elapsed); 
    } 
    pclose($handle); 
    ?> 

回答

4

PHP不是多线程的。 exec()和company将阻止你的脚本,直到exec'd任务完成。使用while()循环没有意义,因为在svn调用完成之前,循环甚至不会开始运行。

如果你想运行多个并行的svn的,你需要使用popen()(或proc_open()),它给你一个文件句柄,从中可以读取外部命令的输出,并在同一时间有多个这样的外部命令。

+0

popen()看​​起来像我所需要的。感谢你的回答。 – CEich

0

因为我明白你的问题,PHP同步执行脚本。这意味着只有在exec命令和输出不会因为已经完成而被改变之后才会运行周期。尝试使用分叉。