【问题标题】:Is there a way to make proc_open read input from a file if the file is dynamic?如果文件是动态的,有没有办法让 proc_open 从文件中读取输入?
【发布时间】: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。
  • 您可以使用某种锁定或信号方法。关键是您需要确保其他进程已完成文件的写入,并且没有自动的方法可以做到这一点。它需要明确的协调。

标签: php proc-open


【解决方案1】:

等待文件创建完成后再使用。

while !file_exists("input.txt") {
    sleep(5)
    // code that uses input.txt
}
...
unlink("input.txt") # Remove file to prepare for next iteration

为避免看到部分文件,创建文件的进程应写入一个临时名称,然后在完成后将其重命名为 input.txt

【讨论】:

  • 考虑 python 程序的前 2 条语句,它们将打印 Hello worldEnter a no,一旦打印出来,那么只有我应该从用户那里获取输入......但是对于这 2 条语句来说输出... proc_open 应该执行... 而要执行 proc_open 我需要为其 stdin 声明 descArray 即文件 input.txt 需要已经存在,最初将为空。但是一旦用户输入值,它将被写入到它,然后只有 proc_open 应该继续进行而不是在那之前..当前它正在继续,即使文件是空的,因此错误。
  • 确保其他程序关闭文件或刷新输出,否则它正在写入的内容将被缓冲。
  • 刚刚意识到我为一个 PHP 问题写了一个 Python 答案,我已经修复了它。
  • 非常感谢!!!这确实有效,但在 Unix 环境下!早些时候我在 Windows 操作系统上尝试过 .. 我将其标记为正确
猜你喜欢
  • 1970-01-01
  • 2022-08-04
  • 2018-06-10
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
  • 2020-08-24
  • 2020-11-17
相关资源
最近更新 更多