如何保持子进程运行并在python中继续为它提供输出?

时间:2016-07-30 17:50:52

标签: python linux ubuntu gdb

我无法保持子进程创建的隧道来激活多个命令。 我首先尝试这个来执行子流程

command=['gdb']
process=subprocess.Popen(command,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
(out,err)=process.communicate("""file demo
b main
r
""")
print out

然后我试了这个

command=['gdb']
process=subprocess.Popen(command,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
process.stdin.write("b main")
process.stdin.write("r")
print repr(process.stdout.readlines())
process.stdin.write("n")
print repr(process.stdout.readlines())
process.stdin.write("n")
print repr(process.stdout.readlines())
process.stdin.write("n")
print repr(process.stdout.readlines())
process.stdin.close()

在第一种情况下它执行命令然后退出gdb使得无法将命令保持到gdb,在第二种情况下它不会在b main命令之后执行(即gdb退出)。
那么我怎样才能继续根据需要从程序中向gdb提供更多命令。以及如何在执行每个命令后获取gdb的输出。
给gdb的命令在开始时是不知道的,它们只能由python程序的用户输入,所以传递长字符串 process.communicate 不会帮忙

2 个答案:

答案 0 :(得分:1)

注意到,communicate()readlines()不适合该任务,因为它们在gdb的输出结束之前不会返回,i。即gdb退出了。我们想要读取gdb的输出,直到它等待输入;一种方法是阅读,直到出现gdb的提示 - 见下面的函数get_output()

from subprocess import Popen, PIPE, STDOUT
from os         import read
command = ['gdb', 'demo']
process = Popen(command, stdin=PIPE, stdout=PIPE, stderr=STDOUT)

def get_output():
    output = ""
    while not output.endswith("\n(gdb) "):  # read output till prompt
        buffer = read(process.stdout.fileno(), 4096)
        if (not buffer): break              # or till EOF (gdb exited)
        output += buffer
    return output

print get_output()
process.stdin.write("b main\n")             # don't forget the "\n"!
print get_output()
process.stdin.write("r\n")                  # don't forget the "\n"!
print get_output()
process.stdin.write("n\n")                  # don't forget the "\n"!
print get_output()
process.stdin.write("n\n")                  # don't forget the "\n"!
print get_output()
process.stdin.write("n\n")                  # don't forget the "\n"!
print get_output()
process.stdin.close()
print get_output()

答案 1 :(得分:0)

我会使用

的内容
with Popen(command, stdin=PIPE, stdout=PIPE) as proc:
    for line in proc.stdout:
        proc.stdin.write("b main")

这将允许您在从流程中读取行时向流程写入行。