2015-10-06 47 views
0

我正在編寫mysqldump的包裝,並希望在PHP CLI應用程序中很好地顯示輸出。嘗試在PHP到mysqldump -v popen和沒有得到輸出

我試圖運行mysqldump -v使用popen,以便我可以得到詳細的輸出和顯示進度指示給用戶。但是沒有返回輸出(默認情況下,它通過stdErr登錄到屏幕)。

我嘗試添加2>&1的命令從stdErr詳細輸出推到stdOut,但仍fread沒有得到,即使輸出通過stdErr nolonger進入到屏幕的任何輸出。

$cmd = "mysqldump -uroot -proot -v dbname 2>&1 | mysql -uroot -proot dbname2"; 
$handle = popen($cmd, "r"); 
$buffer = ""; 
while ($handle && !feof($handle)){ 
    $output = fread($handle, 100); 
    $buffer .= $output; 
    echo sprintf("Buffer: %s\n", $buffer); 
} 
pclose($handle); 

我應該用別的東西代替popen嗎?或者我只是錯誤地重定向輸出?

回答

0

我想通了,而不必使用文件作爲流緩衝區。

/** 
* PROCESS 
* 
* Process the command 
* 
* @param int $buffer The size of the buffer 
* @param int $pipe The pipe to subscribe to (0=stdIn, 1=stdOut, 2=stdErr) 
* 
* @return bool Success or not 
*/ 
public function process($buffer=10, $pipe=1) { 
    $handle = proc_open(
     $this->command, 
     [ 
      ["pipe","r"], 
      ["pipe","w"], 
      ["pipe","w"] 
     ], 
     $pipes 
    ); 
    if (!is_resource($handle)) { 
     return false; 
    } 

    $output = ""; 
    $buffer = ""; 
    $hasLineCallbacks = count($this->onNewLine); 
    while ($buffer = fread($pipes[$pipe], 10)) { 
     $output .= $buffer; 
     if (preg_match("/[\r\n]/", $output)) { 
      $segments = preg_split("/[\r\n]+/", $output); 
      while (count($segments) > 1) { 
       $line = array_shift($segments); 
       if (!$hasLineCallbacks) { continue; } 
       foreach ($this->onNewLine as $callback) { 
        if (!$callback["pattern"] || preg_match($callback["pattern"], $line)) { 
         call_user_func($callback["callback"], $line); 
        } 
       } 
      } 
      $output = array_shift($segments); 
     } 
    } 
    proc_close($handle); 
    return true; 
} 

我基本上使Background類運行一個終端命令和管道輸出到回調函數。顯然還有很長的路要走。

感謝您的幫助,@Victor

+0

$ cmd是'mysqldump -uroot -proot -v dbname | mysql -uroot -proot dbname2' – Rick

+0

該類仍在進行中... https://github.com/Hambrook/CLITaskRunner – Rick

1

您似乎實際上將mysqldump數據傳輸到mysql,在這種情況下,將錯誤消息包含到管道中可能是一個壞主意。

當然,在這種情況下,您無法捕獲mysqldump的輸出。

您應該使用tee命令:

mysqldump -uroot -proot -v dbname | tee /tmp/output | mysql -uroot -proot dbname2 

這種方式,你可以有兩種輸出管道MySQL和/tmp/output。 通過這種方式,您可以使用fopen/tmp/output獲得結果。

請注意,您可能沒有輸出中可能出現的錯誤,因爲mysql不會很高興地看到它們在管道後面。

+0

感謝您的迴應,但它似乎仍然沒有奏效。它只是將'mysqldump'命令的實際輸出放入'/ tmp/output'文件中。 即使使用'tee 2>/tmp/output'進行更新也無法正常工作,因爲它只是mysqldump的標準輸出,它會被傳送到tee。儘管如此,我仍然在玩弄它。 – Rick