我正在寻找一种使用子进程在 Python 3.6 中创建某种终端“克隆”的方法。克隆应该像真正的终端一样运行。目标是让一个 python 脚本模拟一个 shell,它的行为尽可能与普通 shell 一样。包括像cd或变量声明这样的命令。我的目标系统是带有 gnome shell 的 Linux,但我的问题可能与跨操作系统有关。起初我认为这并不难,因为您可以使用子进程轻松运行终端命令,但我遇到了一些问题。我不想做的事情:#!/usr/bin/env pythonimport subprocesswhile True: command = input(" >>> ").rstrip('\n') if command == 'quit': break subprocess.run(command, shell=True)有一种非常简单的方法可以一个接一个地运行命令。问题在于,这将为每个命令启动一个新进程。因此,如果我执行以下命令,它将无法正常工作: >>> lsstackoverflow_subprocess.py >>> cd .. >>> lsstackoverflow_subprocess.py因为我们每次都启动一个新的进程,所以像cd这样的命令没有任何作用。这就是为什么我想在同一个进程中运行所有命令。第一次尝试:#!/usr/bin/env pythonfrom subprocess import PIPE, Popenpipe = Popen("/bin/bash", stdin=PIPE, stdout=PIPE, stderr=PIPE)quit_command = "quit"while True: command = input(" >>> ") if command == quit_command: break command = str.encode(command + "\n") out, err = pipe.communicate(command) print(out,err)这是我第一次尝试解决我的问题。这是我得到的: >>> echo hib'hi\n' b'' >>> echo helloTraceback (most recent call last): File "/home/user/Python/Stackoverflow/subprocess.py", line 11, in <module> out, err = pipe.communicate(command) File "/usr/lib/python3.6/subprocess.py", line 818, in communicate raise ValueError("Cannot send input after starting communication")ValueError: Cannot send input after starting communicationProcess finished with exit code 1所以我不能像这样写多个命令。第二次尝试:#!/usr/bin/env pythonfrom subprocess import PIPE, Popenfw = open("tmpout", "wb")fr = open("tmpout", "r")pipe = Popen("/bin/bash", stdin=PIPE, stdout=fw, stderr=fw, bufsize=1)quit_command = "quit"while True: command = input(" >>> ") if command == quit_command: break command = str.encode(command + "\n") pipe.stdin.write(command) out = fr.read() print(out)然而,这并不奏效。out只是一个空字符串。当我查看它时,我意识到,tmpout在程序完成之前,它的内容不会写入文件。即使您fw在每次迭代之间关闭并重新打开,它仍然只是tmpout在程序完成后写入。问题: 有谁知道解决这些问题的方法吗?即使在通信开始后,是否可以传达更多命令?或者是否有可能在程序结束之前写入文件?或者有谁知道如何获得实际输出,而不仅仅是None最后一次尝试?
添加回答
举报
0/150
提交
取消