Python和子进程-以用户身份打开终端会话并执行一个/两个命令

时间:2019-03-13 09:55:01

标签: python subprocess

尽管我讨厌反省问题,但要达到我将要提出的下一个问题的结果,这是必要的邪恶。

使用python3,tkinter和子流程包,我的目标是编写一个控制面板,以使用一组特定的命令来运行停止不同的终端窗口,以运行{{3 }},包括核心。

因此,我希望控制的每个可执行文件的代码如下:

class TestProc(object):
def __init__(self):
    pass

def start(self):
    self.process = subprocess.Popen(["gnome-terminal", "-c", "'cd /path/to/executable/script.sh; ./script.sh'"])
    print("Process started.")

def stop(self):
    self.process.terminate()
    print("Process terminated.")

当前,可以启动终端窗口和分配的命令/过程,但是仍然存在两个问题:

  • gnome-terminal设置为启动终端窗口,然后释放对内部进程的控制;因此,一旦启动,我将无法控制。一个可能的解决方案是使用xterm,但这会带来许多其他问题。我需要拥有用户.bashrc和/或export
  • 中的变量
  • 某些“全局命令”,例如cdroslaunch对于终端会话将不可用,可能是由于执行顺序(例如,命令在加载bash配置文件之前运行)完全阻止了任何可用的终端

因此,问题响了:我如何能够启动和停止一个新的终端窗口,该窗口在用户环境中最多可以运行两个命令/进程?

1 个答案:

答案 0 :(得分:0)

您可以采取几种方法,这里最灵活也最复杂,因此您需要考虑是否需要这样做。

如果只需要显示脚本的输出,则只需将输出通过管道传输到文件或命名管道。然后,您可以通过读/尾文件来捕获该输出。这是最简单的,只要脚本实际上不需要任何用户交互即可。

如果您真的只需要生成在后台运行的脚本,并且需要模拟用户交互,但实际上并不需要接受实际的用户输入,则可以使用expect方法(使用pexpect库。

如果您需要实际允许真正的用户与该程序进行交互,则有两种方法。首先是您可以将VTE widget嵌入到您的应用程序中,这是最无缝的集成,因为它将使终端看起来与您的应用程序无缝,但是它也是最沉重的。

另一种方法是像在这里一样启动gnome-terminal,这必然会产生一个新窗口。

如果您既需要编写脚本来进行交互,又要允许用户输入,则可以通过在tmux会话中生成脚本来实现。使用tmux send-keys命令使月球互动部分自动化,然后生成一个终端仿真器供用户与tmux attach进行交互。如果您需要在自动化部分和交互式部分之间来回切换,可以将此方法与期望相结合。