让Python在交互式Perl脚本中模拟用户输入

时间:2015-10-16 03:39:15

标签: python perl subprocess

我是编程新手,现在已经捣乱了这个问题......

我正在编写一个Python脚本来自动化基于命令行的交互式Perl脚本,以便它可以在指定目录中的每个文件上运行。我可以使用subprocess.callsubprocess.Popen来启动程序,但是从那里我打开程序并且它在shell中等待用户输入,或者我打开它无数次。我需要每个文件打开一次Perl脚本,接受用户输入(类似于"输入"在每次输入后按下,当然,以及包含文件名称的命令,应该是{ {1}}在下面的示例代码中,使用str(files)的用户输入开始Perl脚本的计算,然后将其关闭。

我知道这是可能的,但我尝试了1000种不同的方法无济于事。有人可以给我一个"解释它就像我' 5"至于我如何让这个Python和Perl脚本相互交谈,好像用户正在输入命令一样?

这是我到目前为止所拥有的:

"4"

我一直在阅读很多关于stdin管道的内容,但并不完全了解它们。它们是用于此问题还是应该使用其他方法?此外,我已经看过Pexpect,但这似乎并没有起作用。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

管道是多个流程进行通信的一种方式,并且广泛用于此。管道是一对文件描述符,其中一个用于写入,另一个用于读取。如果将数据写入前者,则从后者读取将返回相同的数据。

Popen可以为标准输入(stdin),标准输出(stdout)和它执行的进程的标准错误(stderr)文件描述符创建管道 - 但是你必须明确地要求它。这样,您可以向stdin管道写一些内容,这些内容将传递给孩子的stdin。同样,如果要读取子进程的输出,可以从stdout管道中读取。这很符合您的目的,因此您的方法是正确的。

现在让我们看看你的代码:

subprocess.Popen("run_command.command -f a", shell=True)

这将执行命令,但不会创建允许与子进程通信的管道。如果查看documentation,它表示您需要明确要求它通过stdin=subprocess.PIPE等关键字参数创建管道。

time.sleep(3)

通常,逐行接受输入的脚本不关心何时接收输入。所以你应该能够安全地删除它。

Popen.communicate(input="1")

再次查看documentation

  

Popen.communicate(输入=无,超时=无)

     

与流程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。

您只能调用communicate()一次,并且必须将所有输入作为一个字符串传递,并且一旦它终止,它将返回子进程打印的数据。这也意味着对wait()的调用是不必要的。请注意,communicate()会返回一个元组,其中包含孩子打印到stdoutstderr的内容。你可能需要这些。

答案 1 :(得分:1)

为给定目录中的每个文件运行命令:

s = s.replaceAll("[()&,]+", " "); 

请参阅@skmrx's answer,了解当前代码失败的原因。