Как сделать блокировку и прочтение до конца?

Я выполняю скрипт TCL из PHP с помощью proc_open.

  1. Сначала я открываю оболочку TCL. 2) Отправьте команду с помощью fwrite. 3) Мне нужно, чтобы fread ожидал / блокировал, пока команда, посланная fwrite, не будет завершена и не получит все содержимое. Команда может занять некоторое время. (Я могу читать только 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); } ?> 

    Я думаю о сочетании

    • stream_select и / или feof ()
    • fread () и конкатенация частичных результатов ($ result. = fread ())
    • и, возможно, proc_get_status (), чтобы определить конец процесса

    Вы хотите подождать, пока приложение tcl не будет писать что-то в его 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); } ?> за <?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); } ?> того <?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); } ?> за <?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); } ?> того <?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); } ?> 

    Пытаться:

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

    Это ждет?