Sonuna kadar fread engelleme yapmak ve okumak için?

2 Cevap php

Ben proc_open PHP kullanarak bir TCL komut yürütülürken ediyorum.

  1. I first open the TCL shell 2) Send a command using fwrite 3) What I need is fread to wait/block until the command sent by fwrite is complete and get all the contents .The command may take some time to complete. (I am able to read just 2 lines and then it is going off to the next loop)

Birisi bana rehberlik eder.

Mevcut kodu

<?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 Cevap

Ben bir kombinasyonu düşünüyorum

Sen tcl uygulaması (bu son komutun sonu anlamına geldiğini varsayarak) belli bir miktar için stdout için bir şeyler yazmak ve daha sonra kendi stdin'e sonraki komutu / satırı göndermez kadar beklemek istiyorum?

edit:
Seems like you can send all commves to the tcl shell at once ve they are processed one by one, i.e. the shell reads the next input line/commve when it's done with the previous one. I've tested this with the script.

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

ve

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

You probably want to add some more error hveling. E.g. if stream_select() returns x times with an timeout something might have gone wrong.

edit2:
Let the shell print something you can scan for after each script.

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

Deneyin:

$content = '';

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

Bu beklemek mi?