Python基于PyQt5开发一个SSH远程登录终端工具

 更新时间:2026年03月02日 09:40:16   作者:爱吃香肥带鱼的胖圆圆  
这篇文章主要为大家详细介绍了Python如何基于PyQt5和Paramiko开发一个SSH远程登录终端工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

基于 PyQt5 + Paramiko 实现的 SSH 远程登录终端工具,包含服务器管理、多标签终端与远程文件浏览/下载。

效果如下:

环境要求

  • Python >= 3.9
  • Windows 10/11

功能特性

服务器管理

  • 添加、编辑、删除服务器配置
  • 服务器分组管理
  • 配置信息持久化保存

SSH 连接

  • 密码认证
  • 密钥文件认证
  • 每次询问(ask)
  • 连接测试功能

终端界面

  • 交互式 SSH 终端
  • 命令输入与执行
  • 实时输出显示

远程文件浏览器

  • 浏览远程服务器文件系统
  • 查看文件和目录信息
  • 下载文件

多标签页支持

  • 同时连接多个服务器
  • 标签页管理

安装依赖

pip install -r requirements.txt

快速开始(Windows)

安装依赖(见上)。

启动程序(二选一):

  • 方式 A:双击运行 run.bat
  • 方式 B:命令行运行:
python RemoteTerminal_python.py

使用方法

添加服务器

  • 点击“添加服务器”按钮
  • 填写服务器信息(地址、端口、用户名、密码等)
  • 选择认证方式(密码/密钥/每次询问)
  • 点击“保存”

连接服务器

  • 双击服务器列表中的服务器
  • 或右键点击选择“连接”

使用终端

  • 在终端标签页中输入命令
  • 按 Enter 或点击“发送”按钮执行命令

浏览文件

  • 在左侧文件浏览器中浏览远程文件系统
  • 双击目录进入
  • 右键文件可下载

SSH 核心代码说明

连接线程:SSHConnection

  • 继承自 QThread,在独立线程中维护与远程主机的 SSH 会话,避免阻塞 GUI。
  • run() 中使用 paramiko.SSHClient 创建连接,根据是否配置密钥文件选择:
    • 密钥登录:client.connect(..., key_filename=key_file, timeout=10)
    • 密码登录:client.connect(..., password=password, timeout=10)
  • 通过 client.invoke_shell(term='xterm-256color') 创建交互式 SSH shell 通道 channel
  • 持续轮询 channel.recv_ready(),有数据时调用 channel.recv(4096) 并解码为字符串,通过 output_received 信号异步发送给界面。
  • 出现异常时,通过 error_occurred 信号上报错误,在 finally 中统一发出 connection_closed 信号,便于界面做收尾处理。

命令发送与关闭

  • send_command(command) 会在通道仍然可用时执行 self.channel.send(command),通常由终端输入框在用户按下 Enter 时调用(会附带换行符)。
  • close() 方法将 running 置为 False,并关闭底层 channelclient,让线程循环自然退出。

连接测试

  • 在服务器配置对话框中,test_connection() 会临时创建一个 paramiko.SSHClient,用与实际连接相同的参数执行一次 connect / close
  • 成功则弹出“连接测试成功”提示,失败则捕获异常并展示错误信息,便于提前发现账号或网络问题。

示例核心代码:

import os
import time

import paramiko
from PyQt5.QtCore import QThread, pyqtSignal


class SSHConnection(QThread):
    """SSH 连接线程"""
    output_received = pyqtSignal(str)
    error_occurred = pyqtSignal(str)
    connection_closed = pyqtSignal()

    def __init__(self, host, port, username, password=None, key_file=None):
        super().__init__()
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.key_file = key_file
        self.client = None
        self.channel = None
        self.running = False

    def run(self):
        try:
            self.client = paramiko.SSHClient()
            self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            # 连接服务器(密钥优先,其次密码)
            if self.key_file and os.path.exists(self.key_file):
                self.client.connect(
                    hostname=self.host,
                    port=self.port,
                    username=self.username,
                    key_filename=self.key_file,
                    timeout=10,
                )
            else:
                self.client.connect(
                    hostname=self.host,
                    port=self.port,
                    username=self.username,
                    password=self.password,
                    timeout=10,
                )

            # 创建交互式 shell
            self.channel = self.client.invoke_shell(term="xterm-256color")
            self.running = True

            # 持续读取远程输出
            while self.running:
                if self.channel.recv_ready():
                    data = self.channel.recv(4096).decode("utf-8", errors="ignore")
                    if data:
                        self.output_received.emit(data)
                elif self.channel.exit_status_ready():
                    break
                time.sleep(0.1)

        except Exception as e:
            self.error_occurred.emit(str(e))
        finally:
            self.connection_closed.emit()

    def send_command(self, command: str):
        """发送命令到远程 shell"""
        if self.channel and self.running:
            self.channel.send(command)

    def close(self):
        """关闭连接"""
        self.running = False
        if self.channel:
            self.channel.close()
        if self.client:
            self.client.close()

配置说明(servers.json)

服务器配置保存在 servers.json 文件中,包含以下字段:

  • name: 服务器名称
  • host: 服务器地址
  • port: SSH 端口(默认 22)
  • username: 登录用户名
  • password: 登录密码(密码认证时)
  • key_file: SSH 密钥文件路径(密钥认证时)
  • group: 服务器分组
  • auth_method: 认证方式(password / key / ask
  • notes: 备注信息

安全提示:

  • servers.json 可能包含密码等敏感信息,建议仅在本机保存,不要随意分享/上传。
  • 当前实现会在首次连接时 自动接受主机密钥(Paramiko AutoAddPolicy)。在生产环境建议改为校验指纹/已知主机列表,避免中间人风险。
  • 若使用密钥文件,建议使用 绝对路径,并确保密钥权限设置合理。

打包(PyInstaller)

推荐直接使用仓库内的 RemoteTerminalPython.spec

pyinstaller --noconfirm --clean RemoteTerminalPython.spec

如果要用命令行参数方式(Windows 示例,注意 --add-data 分隔符为 ;):

pyinstaller --noconfirm --clean --windowed --onedir --name "RemoteTerminalPython" --add-data "servers.json;." RemoteTerminal_python.py

依赖库

  • PyQt5: GUI 界面框架
  • paramiko: SSH 客户端库

以上就是Python基于PyQt5开发一个SSH远程登录终端工具的详细内容,更多关于Python SSH远程登录的资料请关注脚本之家其它相关文章!

相关文章

  • Python中的re正则表达式模块

    Python中的re正则表达式模块

    这篇文章介绍了Python中的re正则表达式模块,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • python+os根据文件名自动生成文本

    python+os根据文件名自动生成文本

    这篇文章主要为大家详细介绍了python+os根据文件名自动生成文本,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • matplotlib画图之修改坐标轴刻度问题

    matplotlib画图之修改坐标轴刻度问题

    这篇文章主要介绍了matplotlib画图之修改坐标轴刻度问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 关于Python排序问题(冒泡/选择/插入)

    关于Python排序问题(冒泡/选择/插入)

    这篇文章主要介绍了关于Python排序问题(冒泡/选择/插入),学过C语言肯定接触过排序问题,我们最常用的也就是冒泡排序、选择排序、插入排序,需要的朋友可以参考下
    2023-04-04
  • Python利用ansible分发处理任务

    Python利用ansible分发处理任务

    这篇文章主要介绍了Python利用ansible分发处理任务的相关资料,需要的朋友可以参考下
    2015-08-08
  • 浅谈Python_Openpyxl使用(最全总结)

    浅谈Python_Openpyxl使用(最全总结)

    这篇文章主要介绍了浅谈Python_Openpyxl使用(最全总结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Python Flask JinJa2 语法使用示例详解

    Python Flask JinJa2 语法使用示例详解

    这篇文章主要为大家介绍了Python Flask JinJa2 语法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • python numpy数组中的复制知识解析

    python numpy数组中的复制知识解析

    这篇文章主要介绍了python numpy数组中的复制知识解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Django自关联实现多级联动查询实例

    Django自关联实现多级联动查询实例

    这篇文章主要介绍了Django自关联实现多级联动查询实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • python 链接sqlserver 写接口实例

    python 链接sqlserver 写接口实例

    这篇文章主要介绍了python 链接sqlserver 写接口实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03

最新评论