首页 文章

使用python的子进程模块打开python进程

提问于
浏览
2

我正在尝试用python脚本中的不同python解释器进行通信 . 我写了一个对象,它应该存储子进程并读/写它的stdin,stdout,stderr .

import subprocess
import fcntl
import os

class Python:

    def __init__(self):
        self.process = subprocess.Popen("python", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        fcntl.fcntl(self.process.stdout, fcntl.F_SETFL, os.O_RDONLY | os.O_NONBLOCK)
        fcntl.fcntl(self.process.stderr, fcntl.F_SETFL, os.O_RDONLY | os.O_NONBLOCK)

    def read(self):
        stdout = self.process.stdout.read()
        if stdout:
            print("stdout:", stdout)
        stderr = self.process.stderr.read()
        if stderr:
            print("stderr:", stderr)

    def exec(self, line):
        self.process.stdin.write(bytes((line + "\n").encode("ascii")))
        self.process.stdin.flush()

在init函数中创建子进程并将stdout,stderr设置为非阻塞模式 . read函数只是将stdout,stderr打印到屏幕上,exec函数将一行写入python的stdin并刷新它 . 我使用简单的echo脚本测试了这个:

while True:
    print(input())

我能够使用我的exec方法,稍后一段时间读取我使用read方法传递给exec方法的行 .

我的问题是这不适用于python解释器 . 我试图将所有内容写入其标准输入,但它不会向stdout写入任何内容,stderr .

1 回答

  • 1

    好吧,我做了一些测试,你的代码按我的预期工作 . 这意味着您正确创建了一个python解释器并将命令传递给它,并且解释器正确执行它们 .

    问题是管道的输出可能是缓冲的(并且在这里) . 如果你正在编写几千字节,你可以得到开头部分,但是在这里,在Python解释器退出之前,实际上没有任何内容写入管道 .

    确认方式:

    p = Python()
    p.exec("print('foo')")
    p.exec("print('bar')")
    p.process.stdin.close() # force interpreter to exit ...
    time.sleep(0.1) # wait for the interpreter to exit ...
    p.read()
    

    你应该得到 stdout: b'foo\r\nbar\r\n'


    正如J.F.Sebastian在其评论中所建议的那样,不被缓冲困扰的最直接方式就是要求解释器不要使用 -u 选项或 PYTHONUNBUFFERED 环境变量缓冲任何内容:

    class Python:
    
        def __init__(self):
            self.process = subprocess.Popen("python -u", stdin=subprocess.PIPE,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
            ...
    

相关问题