2

proc_open を使用して PHP から TCL スクリプトを実行しています。

  1. 最初に TCL シェルを開きます。 2) fwrite を使用してコマンドを送信します。3) 必要なのは、fwrite によって送信されたコマンドが完了するまで待機/ブロックし、すべての内容を取得する fread です。コマンドが完了するまでに時間がかかる場合があります。(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);
}
?>
4

2 に答える 2

1

の組み合わせを考えています。

  • stream_selectおよび/またはfeof()
  • fread() と部分的な結果の連結 ($result .= fread())
  • そしておそらくproc_get_status()でプロセスの終了を判断します

Tcl アプリケーションが一定時間 (これが最後のコマンドの終了を意味すると仮定して) stdout に何かを書き込まなくなるまで待機してから、次のコマンド/行を stdin に送信しますか?

編集:すべてのコマンドを
tclシェルに一度に送信できるようで、それらは 1 つずつ処理されます。つまり、シェルは、前の入力行/コマンドが完了すると、次の入力行/コマンドを読み取ります。これをスクリプトでテストしました。

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:
各スクリプトの後にスキャンできるものをシェルに出力させます。

<?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);
}
?>
于 2009-08-25T08:25:19.260 に答える
0

試す:

$content = '';

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

それは待っていますか?

于 2009-08-25T08:20:49.783 に答える