如何使fread阻止和读取直到结束?

时间:2009-08-25 07:09:16

标签: php file tcl

我正在使用proc_open从PHP执行TCL脚本。

  1. 我首先打开TCL shell 2)使用fwrite发送命令 3)我需要的是等待/阻止直到 fwrite发送的命令完成 并获取所有内容。该命令可能需要一些时间才能完成。 (我只能阅读2行,然后进入下一个循环)
  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);
    }
    ?>
    

2 个答案:

答案 0 :(得分:1)

我正在考虑

的组合

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

编辑:
似乎就像你可以立即将所有命令发送到tcl shell并逐个处理它们,即shell在完成前一个输入行/命令时读取它。我用脚本测试了这个。

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

答案 1 :(得分:0)

尝试:

$content = '';

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

那等等吗?