如果文件是动态的,有没有办法让 proc_open 从文件中读取输入?
Is there a way to make proc_open read input from a file if the file is dynamic?
我正在尝试使用 proc_open 从文件中读取输入作为进程的标准输入。但是这个文件实际上是动态的,即用户将在另一个进程中输入一些东西到这个文件中。我想要的是 proc_open 应该等到这个文件中添加了一些新内容,然后再将其视为 STDIN。
Here's what I have tried.
<?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 秒之前添加的,那么它应该立即恢复。谢谢!!!
等待文件创建后再使用。
while !file_exists("input.txt") {
sleep(5)
// code that uses input.txt
}
...
unlink("input.txt") # Remove file to prepare for next iteration
为避免看到部分文件,创建文件的进程应写入一个临时名称,然后在完成后将其重命名为 input.txt
。
我正在尝试使用 proc_open 从文件中读取输入作为进程的标准输入。但是这个文件实际上是动态的,即用户将在另一个进程中输入一些东西到这个文件中。我想要的是 proc_open 应该等到这个文件中添加了一些新内容,然后再将其视为 STDIN。
Here's what I have tried.
<?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 秒之前添加的,那么它应该立即恢复。谢谢!!!
等待文件创建后再使用。
while !file_exists("input.txt") {
sleep(5)
// code that uses input.txt
}
...
unlink("input.txt") # Remove file to prepare for next iteration
为避免看到部分文件,创建文件的进程应写入一个临时名称,然后在完成后将其重命名为 input.txt
。