You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:45:43