我希望使用Python 3.5与交互式命令行应用程序进行交互。我的想法是,我在Python脚本的开头启动该过程并将其保持打开状态。在一个循环中,我打印一个文件路径,然后返回一行,到stdin
,等待处理四分之一秒,然后从stdout
读取,直到它到达换行符。
这与communicate
的{{1}}功能非常相似,但我正在等待行返回,而不是等待进程终止。有谁知道一个相对简单的方法吗?
编辑:如果可能,最好使用标准库来执行此操作,而不是使用subprocess
等第三方库。
答案 0 :(得分:2)
您可以使用subprocess.Popen。
这样的事情:
proc = subprocess.Popen(['my-command'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
现在proc.stdin
和proc.stdout
是管道的末端,它们将数据发送到子进程stdin并从子进程stdout读取。
由于您只对阅读换行终止行感兴趣,因此您可以解决因缓冲引起的任何问题。当使用子进程与交互式进程通信时,缓冲是一个很大的陷阱。通常I / O是行缓冲的,这意味着如果子进程没有使用换行终止一行,您可能永远不会在proc.stdout
上看到任何数据,反之亦然,您写入proc.stdin
- 它如果你没有以换行结束,可能看不到它。你可以关闭缓冲,但这不是那么简单,也不是平台无关。
您可能需要解决的另一个问题是,您无法确定子进程是在等待输入还是已经向您发送输出,除非通过写入和读取管道。因此,您可能需要启动第二个线程,以便等待proc.stdout
上的输出并同时写入proc.stdin
而不会遇到死锁,因为两个进程都在管道I / O上阻塞(或,如果您使用的是支持带文件句柄选择的Unix,请使用select
确定哪些管道已准备好接收或准备好从中读取。
答案 1 :(得分:0)
这听起来像是一个事件循环的工作。 subprocess
模块开始显示其在复杂任务下的压力。
我用Twisted做了这个,通过继承以下内容:
twisted.internet.endpoints.ProcessEndpoint
twisted.protocols.basic.LineOnlyReceiver
Twisted的大多数文档都使用套接字作为端点,但调整进程代码并不困难。