Ubuntu18下Gnome Terminal SSH连接后发送命令的Python GUI问题
解决Gnome-Terminal SSH连接后动态发送命令的问题
问题背景
运行Ubuntu 18系统,无法升级,已安装gnome-terminal。作为Python编程新手,现有GUI程序已实现:
- 打开gnome-terminal
- 通过终端连接SSH
但无法实现根据需求动态发送命令,当前代码提示管道破裂,原因是SSH启动后接管了终端的输入输出,原有的subprocess管道无法继续通信。
解决方案:使用tmux控制可见终端
利用tmux终端复用工具,可以在可见的gnome-terminal会话中动态发送命令,无需处理复杂的管道或PTY连接。
步骤1:安装tmux
sudo apt-get install tmux
步骤2:修改Python代码
以下是完整的可运行代码,包含终端启动、SSH连接、动态发送命令的功能:
import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk import subprocess class Application(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) # 定义唯一的tmux会话名称,避免冲突 self.ssh_session_name = "ssh_core_session" def do_activate(self): window = Gtk.Window(application=self) window.set_title("SSH Terminal Controller") box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) box.set_size_request(300, 200) # 启动SSH终端按钮 btn_open_terminal = Gtk.Button(label="Open Core SSH Terminal") btn_open_terminal.connect("clicked", self.on_open_ssh_terminal) box.pack_start(btn_open_terminal, True, True, 0) # 发送ls命令按钮 btn_send_ls = Gtk.Button(label="Send 'ls' Command") btn_send_ls.connect("clicked", self.on_send_ls) box.pack_start(btn_send_ls, True, True, 0) # 查看核心日志按钮 btn_show_logs = Gtk.Button(label="Show Core Logs") btn_show_logs.connect("clicked", self.on_show_core_logs) box.pack_start(btn_show_logs, True, True, 0) window.add(box) window.show_all() def on_open_ssh_terminal(self, widget): # 构建SSH命令:加载密钥 + 自动接受主机指纹 + 连接SSH ssh_cmd = "ssh-add /home/ssh_key; ssh -o StrictHostKeyChecking=no root@xxx.xx.x.xx; exec bash" # 用tmux创建新会话,启动gnome-terminal运行该会话 tmux_cmd = f"tmux new-session -s {self.ssh_session_name} '{ssh_cmd}'" subprocess.Popen(["gnome-terminal", "--", "bash", "-c", tmux_cmd]) def on_send_ls(self, widget): # 发送ls命令到tmux会话,C-m模拟回车键执行命令 subprocess.run(["tmux", "send-keys", "-t", self.ssh_session_name, "ls", "C-m"]) def on_show_core_logs(self, widget): # 发送日志查看命令,可根据需求修改路径 subprocess.run(["tmux", "send-keys", "-t", self.ssh_session_name, "tail -f /var/log/core.log", "C-m"]) app = Application() exit_status = app.run(None)
原理说明
- 用
gnome-terminal启动一个tmux会话,该会话会自动执行SSH连接命令 - 通过
tmux send-keys命令,可向指定的tmux会话发送按键事件(相当于手动在终端输入命令并回车) - 终端全程可见,所有命令执行结果会直接显示在终端窗口中
注意事项
- 如果SSH密钥需要密码,可在
ssh-add命令后添加超时参数:ssh-add -t 3600 /home/ssh_key(3600秒内无需重复输入密码) - 若终端窗口关闭,再次发送命令会报错,可添加会话存在性检查:
在发送命令前调用该函数,若会话不存在可提示用户重新打开终端。def is_session_alive(self): return subprocess.run(["tmux", "has-session", "-t", self.ssh_session_name], stderr=subprocess.DEVNULL).returncode == 0
内容的提问来源于stack exchange,提问作者Mihai Andrei
相关产品推荐
相关产品推荐

