Python子进程:检查执行的脚本是否需要用户输入

9
import subprocess

child = subprocess.Popen(['python', 'simple.py'], stdin=subprocess.PIPE)
child.communicate('Alice')

我知道你可以通过通信与执行的脚本进行交流。

如何检查脚本“simple.py”是否正在请求用户输入?

simple.py可能会要求5-10个用户输入,因此仅硬编码communicate是不够的。

[编辑]:希望在脚本运行时解析stdout并与脚本进行通信。

while True:
    if child.get_stdout() == '?':
       # send user input

1
你不能这样做。程序不会主动要求输入,它们只会等待输入的到来。 - zondo
1
你就是不能。当程序等待输入时,它只是无所事事地等待直到得到输入。有很多原因会导致程序无所作为,所以我们无法确定它是否正在等待输入。 - zondo
@zondo 我想要能够做类似于编辑部分的事情 - ealeon
您需要编写到标准输入(stdin),并从标准输出(stdout)解析。 - Padraic Cunningham
1
你可以在/proc/<pid>/wchan中检查等待通道,或者使用ptrace/strace或其他你喜欢的方法跟踪子进程。 - Andrea Corbellini
显示剩余4条评论
1个回答

2
一个简单的例子:
simple.py:
i = raw_input("what is your name\n")
print(i)
j = raw_input("What is your age\n")
print(j)

读写:

import subprocess

child = subprocess.Popen(['python2', 'simple.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

for line in iter(child.stdout.readline, ""):
    print(line)
    if "name" in line:
        child.stdin.write("foo\n")
    elif "age" in line:
        child.stdin.write("100\n")

输出:

what is your name

foo

What is your age

100

1
谢谢!这正是我在寻找的。 - ealeon
2
@ealeon:小心,除非你确切知道应该写/读多少;否则如果输入/输出不同步,很容易挂起子进程(如果尝试读取过多,则可能无限期等待永远不会到来的输入,或者如果尝试写入过多,则一旦相应的操作系统管道缓冲区已满,则write可能会阻塞)。一般来说,如果处理多个管道(如此情况),则应使用线程或异步I/O。 - jfs
@jfs 能否详细说明一下?你的评论是否特别针对上面的示例代码,即子进程可能正在等待输入,但由于父循环的影响而无法接收到输入?或者在同时使用 stdinstdout 管道时还有其他需要注意的地方吗? - Michael Harris
1
@MichaelHarris:我的评论是关于一般方法的(加上/减去无关的块缓冲问题,答案中的代码可能有效)。这里有一个演示如果读/写未完全同步且使用同步读/写会发生什么的代码:https://gist.github.com/zed/dc609d81ce72b3ec9a5619ff0262d889 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接