【发布时间】:2019-10-20 15:35:59
【问题描述】:
我正在尝试从文件中读取输入作为使用 proc_open 的进程的标准输入。但是这个文件实际上是动态的,即用户将在另一个进程中输入一些东西到这个文件中。我想要的是 proc_open 应该等到在这个文件中添加了一些新内容,然后再将其视为 STDIN。
这是我尝试过的。
<?php
$desc = array(
0 => array('file', 'input.txt','r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
//$cmd = "java Main";
$cmd="python sample.py";
$proc = proc_open($cmd, $desc, $pipes);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
//stream_set_blocking($pipes[0], 0);
if($proc === FALSE){
throw new Exception('Cannot execute child process');
}
$status=proc_get_status($proc);
$pid = $status['pid'];
while(true) {
$status = proc_get_status($proc);
if($status === FALSE) {
throw new Exception ("Failed to obtain status information for $pid");
}
if($status['running'] === FALSE) {
$exitcode = $status['exitcode'];
$pid = -1;
echo "child exited with code: $exitcode\n";
exit($exitcode);
}
$a=0;
//fwrite($pipes[0],"10\n");
foreach(array(1, 2) as $desc) {
// check stdout for data
$read = array($pipes[$desc]);
$write = NULL;
$except = NULL;
$tv = 0;
$utv = 50000;
$n = stream_select($read, $write, $except, $tv, $utv);
if($n > 0) {
do {
$data = fread($pipes[$desc], 8092);
//echo "tp".$data;
//$a=$a+1;
//echo $a."\n";
fwrite(STDOUT, $data);
} while (strlen($data) > 0);
// echo "Hey". $desc;
}
}
/* $read = array(STDIN);
$n = stream_select($read, $write, $except, $tv, $utv);
if($n > 0) {
echo "Inside input stream";
$input=10;
fwrite($pipes[0], $input);
}else{
echo "Not working";
}*/
}
?>
当我运行一个带有 input.txt 文件为空的示例程序时,输出是这样的:
示例 python 程序
print("Hello world")
x=input("Enter a no: ")
print(x)
y=input("Enter any string: ")
print(y)
print(y+str(x))
输出: Output of running python program with php script above
正如您在输出中看到的那样,当预期变量 y 的输入时,会出现错误,因为 input.txt 文件还没有该值。我希望它等待一段时间,比如 30 秒,然后只读取新添加的内容,但如果它是在 30 秒之前添加的,那么它应该立即恢复。谢谢!!!
【问题讨论】:
-
让其他进程将数据写入不同的文件名,如
input.temp,然后在完成后将其重命名为input.txt。然后PHP脚本可以循环,等待文件存在。 -
@Barmar 但这只会解决第一个输入的问题......假设在每次输入后预期有 3 个输入我需要删除文件......同样一旦脚本出来你提到的循环......程序执行的过程已经开始,然后就没有回来了!
-
您需要在处理完文件后将其删除,这样每次都能正常工作。
-
如果您有任何其他方法可以想到,请分享...。我正在尝试为网站的程序执行制作交互式外壳...所以一旦生成输出。 . 用户输入输入,并将其写入文件 input.txt,该文件充当 proc_open 的 STDIN。
-
您可以使用某种锁定或信号方法。关键是您需要确保其他进程已完成文件的写入,并且没有自动的方法可以做到这一点。它需要明确的协调。