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

时间:2018-09-10 14:25:05

标签: python linux pipe ipc

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

我需要以交互模式运行Python,即使用输入管道向其传递一个命令,然后等待输出管道上的答案。一切都很好,但是似乎Python只有在stdinstdout连接到tty的情况下才能运行交互模式。

Python文档引用:

  

解释器的运行方式与Unix shell相似:当通过连接到tty设备的标准输入进行调用时,它以交互方式读取和执行命令。当使用文件名参数或以文件作为标准输入调用时,它将读取并执行该文件中的脚本。

实际上,当我使用管道而不是tty运行解释器时,发送命令后,响应管道中什么也看不到。

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

同样,问题简而言之:

我需要将Python集成到我的C ++服务器应用程序中,以允许客户端执行python命令。 将解释器嵌入到服务器中似乎是一个坏主意,主要是出于安全考虑(用户可能会损坏服务器或其数据,此外服务器正在以我不想授予用户的特权运行)。

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

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

无论如何,如果您有任何建议,我将很高兴为您提供帮助。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

您正在做的事情确实很奇怪和不寻常。交互式外壳旨在通过人工键入命令进行交互式使用。它不是为输入来自另一个程序的交互式脚本而设计的。

话虽如此,是的,您可以执行此操作,尽管我确实不建议这样做。您要做的是运行一个脚本,该脚本读取命令的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的观点,无论如何这看起来都是一个错误的问题。解决实际问题的方法可能比这样做更好,更轻松。您真正想要做什么?