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);
}