php 的 popen 與 exec
exec() 最大的問題應該是,如果呼叫的 process 有print out 資料或其中有個 thread 有 return,都可能讓 exec() 以為 process 結束。
這次遇到的是該執行檔如果是 process 第一次啟動的時候,會先把一些資料先載入記憶體,然後成為背景程式。而將資料載入記憶體時是交給另一個 thread 去做,並印出 loading information。用 exec 的話,會誤判呼叫結束,而沒有抓到正確的執行結果。
改用 popen 並用 process handle 去讀取執行的 stdout 會是比較好的 solution。
//exec("cd " . $this->config->program_root . "; sudo " . $this->config->program . " " . $this->config->model . " " . $this->config->datafile_folder . $newfi lename, $output, $returnvalue); $handle = popen("cd " . $this->config->program_root . "; sudo " . $this->config->program . " " . $this->config->model . " " . $this->config->datafile_folder . $newfilename, "r"); $read = fread($handle, 2096); if (strpos($read, 'LOAD MODEL') !== false) { //sleep(1); $read = fread($handle, 2096); } $output = explode("\n", $read); pclose($handle); // 要記得 close foreach ($output as $line) { error_log($line); }
Original link: Phanix's Blog