2011-08-29 58 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命令和輸出不會因爲已經完成而被改變之後纔會運行週期。嘗試使用分叉。