2017-02-26 41 views
8

我的命令行腳本有問題.. PHP腳本不會繼續..腳本在命令行後不能繼續

試圖通過putty直接調用命令行並輸出很多錯誤但立即返回/完成。爲什麼不返回到PHP?

它正常工作與其他PDF文件,但沒有這一項

PDF

http://docdro.id/b0M5vfw

代碼

$Cmd = new Command; 
if($err = $Cmd->exec('/var/bin/poppler-0.51.0/utils/pdfimages -list /var/test.pdf')){ 
    echo "ERR: $err\n"; 
} 
echo "continue\n"; 

class Command { 
    private $descriptorspec; 

    private $output = ''; 

    private $process; 
    private $pipes = []; 

    public function __construct(){ 
     $this->descriptorspec = [ 
      0 => ['pipe', 'r'], // stdin 
      1 => ['pipe', 'w'], // stdout 
      2 => ['pipe', 'w'] // stderr 
     ]; 
    } 

    public function output(): string{ 
     return $this->output; 
    } 

    public function close(){ 
     foreach($this->pipes as $pipe){ 
      if(is_resource($pipe)){ 
       fclose($pipe); 
      } 
     } 

     proc_close($this->process); 
    } 

    public function exec(string $syntax){ 
     $this->process = proc_open($syntax, $this->descriptorspec, $this->pipes); 
     fclose($this->pipes[0]); 

     $this->output = stream_get_contents($this->pipes[1]); 

     $stderr = stream_get_contents($this->pipes[2]); 

     $this->close(); 

     return $stderr; 
    } 
} 

錯誤

# /var/bin/poppler-0.51.0/utils/pdfimages -list /var/test.pdf 
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio 
-------------------------------------------------------------------------------------------- 
    1  0 image 2154 303 rgb  3 8 jpeg yes [inline]  289 292 - - 
Syntax Error (50560): Illegal character '>' 
Syntax Error (50560): Unknown operator '<10><07><82>;w<ad><a2><b4>2r<1f><10><07><8f>~j<c4>Hq<cf>Z<86>' 
Syntax Error (50568): Unknown operator '<0f><b5>X<8f><ae><d0>:<d7>DU<91><cb>'v' 
Syntax Error (50568): Illegal character ')' 

........ 

Syntax Error (66698): Illegal character <04> in hex string 
Syntax Error (66699): Illegal character <ff> in hex string 
Syntax Error (66699): Illegal character <c1> in hex string 
Syntax Error (66705): Unknown operator '<9b>' 
Syntax Error (66714): Illegal character ')' 
Syntax Error (66714): Unknown operator '<bc>q<ff>' 
Syntax Error (66720): Unknown operator '<05>6<f8><c2><fa><d7><c3>?<f8>' 
Syntax Error (66741): Unknown operator '<df><ec><99><e1>-' 
Syntax Error (66743): Unknown operator ']' 
Syntax Error (66762): Unknown operator '<cc>' 
Syntax Error: Unterminated string 
Syntax Error: End of file inside array 
Syntax Error: End of file inside array 
Syntax Error: Leftover args in content stream 
+0

你的命令是否要求用戶(你)的任何輸入? –

+0

@AdarshSojitra不,它不是 – clarkk

+1

只是很快,我很確定這個PDF正在死亡,因爲內容流包含一個由'BI'開頭的內聯圖像,隨後是隨機數據,並以'EI'結尾。 Adobe工程師在設計這些操作員時有一天不休息,問題在於二進制數據隨機包含「EI」並使PDF不可分析的情況。有些工具可以更好地處理這個問題,但理想情況下,此圖像的製作者應避免使用內嵌圖像。 – dwarring

回答

7

的PDF是有問題的 - @dwarring已經逃避了這個在評論中(這裏引用貸記評論者)

@dwarring說:「只是快,我敢肯定,此PDF正在死亡,因爲內容流包含以'BI'開頭的內聯圖像,隨後是隨機數據,並以'EI'結尾。 Adobe工程師在設計這些操作員時有一天不休息,問題在於二進制數據隨機包含「EI」並使PDF不可分析的情況。有些工具可以處理這更好的,但理想的這一形象的生產者應避免使用內嵌的圖像。」

從事物的PHP的一面,但是,而不是if語句使用try/catch塊和你應該保留腳本的控制。

$Cmd = new Command; 

try { 
    $err = $Cmd->exec('/var/bin/poppler-0.51.0/utils/pdfimages - list/var/test.pdf')){ 
} catch (Exception $e) { 
    var_log($e); 
} 

echo "continue\n"; 
1

你可以結合使用stream_selectfeof檢查其中兩個讀取流有數據可用,如下面的代碼。

我測試過它(使用PHP 7),它不會在這裏阻止(做出修改)。是必要的,因爲以下(從http://php.net/manual/en/function.stream-select.php引用)

public function exec(string $syntax){ 
     $this->process = proc_open($syntax, $this->descriptorspec, $this->pipes); 
     fclose($this->pipes[0]); 

     $stderr = ""; 

     $num_changed_streams = NULL; 
     while (!feof($this->pipes[1]) || !feof($this->pipes[2])) { 
      $read = [$this->pipes[1], $this->pipes[2]]; 
      $write = NULL; 
      $err = NULL; 
      $num_changed_streams = stream_select($read, $write, $err, 3); 
      if ($num_changed_streams === false) { 
      $this->close(); 
      return $stderr; 
      } else { 
      if (isset($read[0])) { 
       $this->output .= stream_get_contents($read[0]); 
       echo "output: {$this->output} "; 
      } 
      if (isset($read[1])) { 
       $stderr .= stream_get_contents($read[1]); 
       echo "stderr: {$stderr}"; 
      } 
      } 
     } 
     $this->close(); 
     return $stderr; 
    } 

stream_selectfeof功能:

讀陣列中列出的流將被觀看,以查看是否字符變爲可用於讀取(更確切地說,查看讀取是否不會被阻塞 - 特別是流文件在文件結束時也已準備就緒,在這種情況下,fread()將返回零長度的字符串)。

0

的問題是,這個方案/var/bin/poppler-0.51.0/utils/pdfimages不寫什麼到stdout和你的代碼掛起,在$this->output = stream_get_contents($this->pipes[1]);因此類是不適合這個節目。對於不寫任何內容到stdout的程序,您不得從$this->pipes[1]讀取。你應該有一個用於這種特定類型的應用其它類:

class CommandWithNoOutput { 
    private $descriptorspec; 

    private $process; 
    private $pipes = []; 
    private $output = ''; 

    public function __construct(){ 
     $this->descriptorspec = [ 
      0 => ['pipe', 'r'], // stdin 
      1 => ['pipe', 'w'], // stdout 
      2 => ['pipe', 'w'] // stderr 
     ]; 
    } 

    public function output(): string{ 
     return (string)$this->output; 
    } 


    public function close(){ 
     foreach($this->pipes as $pipe){ 
      if(is_resource($pipe)){ 
       fclose($pipe); 
      } 
     } 

     proc_close($this->process); 
    } 

    public function exec($syntax){ 

     $this->process = proc_open($syntax, $this->descriptorspec, $this->pipes); 
     fclose($this->pipes[0]); 

     $stderr = stream_get_contents($this->pipes[2]); 

     $this->close(); 

     $this->output = ob_get_clean(); 

     return $stderr; 
    } 
} 

$Cmd = new CommandWithNoOutput; 
if($err = $Cmd->exec('/usr/bin/pdfimages -list test.pdf')){ 
    echo "ERR: $err\n"; 
} 
echo "continue\n"; 

此代碼將是:

ERR: Syntax Error (50560): Illegal character '>' 
Syntax Error (50560): Unknown operator '<10><07><82>;w<ad><a2><b4>2r<1f><10><07><8f>~j<c4>Hq<cf>Z<86>' 
Syntax Error (50568): Unknown operator '<0f><b5>X<8f><ae><d0>:<d7>DU<91><cb>'v' 
Syntax Error (50568): Illegal character ')' 
Syntax Error (50570): Unknown operator '<15><c7>=j<c4>X<f4><e8>' 
.....a lot of errors..... 
Syntax Error (66762): Unknown operator '<cc>' 
Syntax Error: Unterminated string 
Syntax Error: End of file inside array 
Syntax Error: End of file inside array 
Syntax Error: Leftover args in content stream 

continue 

Process finished with exit code 0 

UPDATE: 另一種解決方法是調用proc_open所以後立即打電話給stream_set_blocking($this->pipes[1], 0);代碼不會等待任何輸出。

相關問題