当前位置: 代码网 > it编程>前端脚本>Python > Python基于PyQt5开发一个SSH远程登录终端工具

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

2026年03月02日 Python 我要评论
基于 pyqt5 + paramiko 实现的 ssh 远程登录终端工具,包含服务器管理、多标签终端与远程文件浏览/下载。效果如下:环境要求python >= 3.9windows 10/11功

基于 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远程登录的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com