我正在编写一个C ++程序,该程序将作为子进程运行Python 3解释器,然后连接两个Linux匿名管道-一个连接到stdout
和stderr
,另一个连接到解释器的{ {1}};接下来通过这些渠道与之沟通。
我需要以交互模式运行Python,即使用输入管道向其传递一个命令,然后等待输出管道上的答案。一切都很好,但是似乎Python只有在stdin
和stdout
连接到tty的情况下才能运行交互模式。
Python文档引用:
解释器的运行方式与Unix shell相似:当通过连接到tty设备的标准输入进行调用时,它以交互方式读取和执行命令。当使用文件名参数或以文件作为标准输入调用时,它将读取并执行该文件中的脚本。
实际上,当我使用管道而不是tty运行解释器时,发送命令后,响应管道中什么也看不到。
那么-我可以通过某种方式解决这种问题,并使python3解释器完全按照用户从终端启动的方式工作吗?
同样,问题简而言之:
我需要将Python集成到我的C ++服务器应用程序中,以允许客户端执行python命令。 将解释器嵌入到服务器中似乎是一个坏主意,主要是出于安全考虑(用户可能会损坏服务器或其数据,此外服务器正在以我不想授予用户的特权运行)。
另一种可能的解决方案是以CLI方式(命令模式)使用解释器。主要问题是-然后,我需要导入一些模块并预先执行一些代码,以向用户提供服务器环境和一些API。在每条命令调用解释器之前,这样做会很繁重(这些动作非常复杂,包括建立网络连接)
因此,在单独的进程中运行解释器,并使用IPC机制与服务器进行通信似乎不是一个坏主意。
无论如何,如果您有任何建议,我将很高兴为您提供帮助。
答案 0 :(得分:2)
您可以按cli方式使用python,每次运行命令用户输入的命令,或将它们归档在文件中并按输入的每一行运行。这样,您可以更简单地使用它的输出。希望会有用。
答案 1 :(得分:1)
如果您确实需要子进程认为它正在与终端通信,则可以使用伪终端或pty来实现。有两种不同的API,一种来自BSD Unix,一种来自System V,Linux都支持。请参见What do pty and tty mean?或查看forkpty
或posix_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的观点,无论如何这看起来都是一个错误的问题。解决实际问题的方法可能比这样做更好,更轻松。您真正想要做什么?