2009-08-25 50 views
2

我正在使用proc_open从PHP执行TCL脚本。如何让fread阻止并阅读直到结束?

  1. 我先打开TCL外壳 2)使用发送命令的fwrite 3)我需要的是FREAD等待/块,直到FWRITE发送的 命令完成 并获得所有内容.The命令可能需要一些时间才能完成。 (我能够只读2行,然后它将进入下一个循环)

有人可以指导我。

本代码是

<?php 

$app = 'tclsh84'; 
$descriptorspec = array(
0 => array("pipe","r"), 
1 => array("pipe","w"), 
2 => array("file","C:/wamp/www/tcl/bin/g.txt","w") 
) ; 
$process = proc_open($app, $descriptorspec, $pipes); 
if (is_resource($process)) 
{ 


for($i=0;$i<4;$i++) 
{ 

fwrite($pipes[0], 'source c:/wamp/www/tcl/bin/test.tcl'."\n"); 
$content= fread($pipes[1],8192) 
print "$content"; 

}  
    fclose($pipes[0]);  

    fclose($pipes[1]); 


    proc_close($process); 
} 
?> 
+0

您确定脚本生成的输出比您获得的更多吗? fread的php文档表明,除非遇到EOF(如果从用户空间流读取),否则它不会返回小于指定的数量。 – Inshallah 2009-08-25 07:21:05

+0

Fread不会停止TCL上的命令来完成。它进入下一个循环。 – Vidya 2009-08-25 07:33:52

回答

1

我在考虑的

您想等到tcl应用程序不向某个特定amo的stdout写入某些内容没有时间(假设这意味着最后一个命令结束),然后发送下一个命令/行到它的stdin?

编辑:
似乎一样可以一次发送的所有命令到TCL外壳和它们被处理一个接一个,即壳读取时,它与前一个完成的下一个输入行/命令。我已经用脚本测试过了。

incr a 1 
after 1000 
puts [concat [clock seconds] $a] 

<?php 
$app = 'c:/programme/tcl/bin/tclsh85.exe'; 
$descriptorspec = array(
    0 => array("pipe","r"), 
    1 => array("pipe","w"), 
    2 => array("file","C:/god.txt","w") 
) ; 
$process = proc_open($app, $descriptorspec, $pipes); 
if (is_resource($process)) { 
    fwrite($pipes[0], "set a 1\n"); 
    for($i=0;$i<4;$i++) { 
    fwrite($pipes[0], "source c:/helloworld.tcl\n"); 
    } 
    // when all scripts are done the shell shall exit 
    fwrite($pipes[0], "exit\n"); 
    fclose($pipes[0]); 

    do { 
    $read=array($pipes[1]); $write=array(); $except=array($pipes[1]); 
    // wait up to 1 second for new output of the tcl process 
    $ready = stream_select($read, $write, $except, 1, 0); 
    if ($ready && $read /* is not empty */) { 
     // get the partial output 
     $r = fread($pipes[1], 2048); 
     echo $r; 
    } 
    // is the process still running? 
    $status = proc_get_status($process); 
    } while($status['running']); 
    fclose($pipes[1]); 
    proc_close($process); 
} 
?> 

你可能想添加一些错误处理。例如。如果stream_select()返回x次超时,可能会出现错误。

edit2:
让shell打印每个脚本后可以扫描的内容。

<?php 
// something that's not in the "normal" output of the scripts 
$id = 'done'. time(); 

$app = 'c:/programme/tcl/bin/tclsh85.exe'; 
$descriptorspec = array(
    0 => array("pipe","r"), 
    1 => array("pipe","w"), 
    2 => array("file","C:/god.txt","w") 
) ; 
$process = proc_open($app, $descriptorspec, $pipes); 
if (is_resource($process)) { 
    fwrite($pipes[0], "set a 1\n"); 
    for($i=0;$i<4;$i++) { 
    $output = ''; 
    $continue = true; 
    $cTimeout = 0; 
    echo 'loop ', $i, "\n"; 
    fwrite($pipes[0], "source c:/helloworld.tcl\n"); 
    fwrite($pipes[0], "puts $id\n"); 
    echo "waiting for idle\n"; 
    do { 
     $read=array($pipes[1]); 
     $write=array(); 
     $except=array($pipes[1]); 
     $ready = stream_select($read, $write, $except, 1, 0); 
     if ($ready && $read) { 
     $output .= fread($pipes[1], 2048); 
     // if the delimiter id shows up in $output 
     if (false!==strpos($output, $id)) { 
      // the script is done 
      $continue = false; 
     } 
     } 
    } while($continue); 
    echo 'loop ', $i, " finished\n"; 
    } 
    proc_close($process); 
} 
?> 
+0

我正在发送一个命令(要执行的proc名称)。我想等到它完成执行。有没有办法等待? 我不需要读取它发送的数据,我只需要等到它完成。 – Vidya 2009-08-25 11:37:41

+0

你到底什么时候需要等待?您将字符串'source xyz'四次发送到进程的标准输入。在发送另一个“源......”之前,您是否必须等待每个脚本的处理?还是你(只)必须等到所有脚本(全部)完成? – VolkerK 2009-08-25 11:45:09

+0

我必须等待每个脚本调用(tcl中的proc)才能完成。希望你明白我的观点。在我的情况下,我不得不等待4次。 – Vidya 2009-08-25 11:48:02

0

尝试:

$content = ''; 

while(!feof($pipes[1])) 
{ 
    $content .= fread($pipes[1],8192); 
} 

这是否等待?

+0

不,它不会等待。好的我有什么办法可以等待,直到通过fwrite发送的命令完成了吗? – Vidya 2009-08-25 11:36:07