Я думаю о комбинации
Вы хотите дождаться, пока приложение tcl не напишет что-то в его stdout для определенного amo (предполагая, что это означает конец последней команды), а затем отправить следующую команду/строку в свой 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 раз с таймаутом, что-то могло бы пойти не так.
Редактировать2:
Позвольте оболочке напечатать то, что вы можете сканировать для каждого скрипта.
<?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 для fread предполагает, что она не вернется меньше указанной суммы, если только она не встречает EOF (при чтении из потока пользовательского пространства). – Inshallah
Fread не останавливается для завершения команды TCL. Он переходит к следующему циклу. – Vidya