使用管道进行Python进程输入/输出

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用管道进行Python进程输入/输出相关的知识,希望对你有一定的参考价值。

我正在编写一个C ++程序,它将作为子进程运行Python 3解释器,然后连接两个Linux匿名管道 - 一个用于它的stdoutstderr,第二个用于解释器的stdin;接下来通过这些渠道与之沟通。

我需要以交互模式运行Python,即使用输入管道将一个命令传递给它并等待输出管道上的答案。一切都很好,但似乎只有当stdoutstdin连接到tty时,Python才能运行交互模式。

Python文档引用:

解释器的操作有点像Unix shell:当使用连接到tty设备的标准输入调用时,它以交互方式读取和执行命令;当使用文件名参数或文件作为标准输入调用时,它会从该文件中读取并执行脚本。

实际上,当我使用管道而不是tty运行解释器时,在命令发送后,我无法在响应管道中看到任何内容。

那么 - 我可以通过某种方式解决这种行为,并使python3解释器完全按照用户从终端启动的方式工作吗?

同样,问题简而言之:

我需要将Python集成到我的C ++服务器应用程序中,以允许客户端执行python命令。将解释器嵌入到服务器看起来是个坏主意,主要是出于安全考虑(用户可能损坏服务器或其数据,除了服务器运行时我还不想向用户授予某些权限)。

另一种可能的解决方案是以CLI方式使用解释器(命令模式)。主要问题是 - 然后我需要导入一些模块并预先执行一些代码来为用户提供我的服务器环境和一些API。在用每个命令调用解释器之前做它太重了(这些动作非常复杂,包括建立网络连接)

因此,在一个单独的进程中运行解释器,服务器使用IPC机制与它进行通信似乎并不是一个坏主意。

无论如何,如果你有任何建议,我很乐意看看你的建议。

答案

您可以以cli方式使用python,每次运行用户输入的命令,或将它们存档在文件中并按输入的每行运行。通过这种方式,您可以更简单地使用它的输出。希望有用。

另一答案

如果你真的需要子进程认为它正在与终端通信,你可以使用伪终端或pty来实现。有两种不同的API,一种来自BSD Unix,另一种来自System V,而Linux则支持两者。请参阅What do pty and tty mean?或查看forkptyposix_openpt的手册页。

但是,在这种情况下,我的猜测是python解释器阻止缓冲其输出。您可以通过使用-u调用它来禁用stdin / stdout上的缓冲来测试它。

另一答案

你正在做一些非常奇怪和不寻常的事情。交互式shell旨在用于交互式使用,具有人类输入命令。它不是为交互式脚本而设计的,其中输入来自另一个程序。

话虽如此,是的,你可以做到这一点,虽然我真的不会推荐它。你想要做的是运行一个脚本,它读取命令的stdin,然后调用exec()方法。

简单版本可能如下所示:

while True:
    lines = []
    while True:
        line = input()
        if line == "":
            exec("\n".join(lines))
            break
        else:
            lines.append(line)

当接收多行输入时,上述程序的行为类似于python shell,因为交互式命令被缓冲并且在连续的空换行之前不执行。

对于脚本/程序化用法,您可能需要一个比双换行更强大的块标记。例如,您可能希望中断具有空字符的命令块,以便您可以安全地执行包含空行的脚本。

FWIW,我同意John Kugelman的观点,无论如何这看起来都是错误的问题。有可能比做这样的事情更好更容易地解决你的实际问题。你真正想做的是什么?

以上是关于使用管道进行Python进程输入/输出的主要内容,如果未能解决你的问题,请参考以下文章

Python使用管道处理输入/输出

两个子进程之间的 Python 管道输出

文件输入输出的管理以及管道的使用

使用管道在父进程和子进程之间进行通信的问题

将批处理文件输出管道传输到 Python 脚本

使用带有标准输入和标准输出重定向的 2 进程管道时如何避免标准输入上的重复输入