python脚本 链接到ssh服务器 快速登录ssh服务器 ssh登录

news2025/1/19 3:18:29

此文分享一个python脚本,用于管理和快速链接到ssh服务器。

效果演示

  • 🔥完整演示效果
    20231223181233_rec_

  • 👇第一步,显然,我们需要选择功能
    20231223171745

  • 👇第二步,确认 or 选择ssh服务器,根据配置文件中提供的ssh信息,有以下情况

    • 👇场景一,只有一个候选ssh服务器,则脚本会提示用户是否确认链接到该ssh服务器
      20231223171947

    • 👇场景二,如果有多个候选ssh服务器,则脚本会提示用户选择目标ssh服务器
      20231223173332

    • 👇场景三,如果我们不划计登录配置中所列的ssh服务器,我们亦可以指定其它的ssh接口
      20231223173456

  • 👇第三步,当我们选择、确认或者指定了ssh服务器后,即可登入ssh服务器
    20231223173643

配置文件

我们需要在配置文件中记录和管理一些配置信息,例如上文中提到的ssh登录信息,例如用于文档搜索的everything接口信息等。这是一个json文档(cfg.json),如下👇:

{
   
"ssh接口列表":[{
   "主机名称":"virtualBox","主机地址":"192.168.56.1","端口号":22,"用户名":"dyy","密码":"123456"}],
"everythingIP":"127.0.0.1",
"everythingPort":"22"
}

或者,可以直接下载文档

python脚本

👇以下脚本,提供了以上👆所演示的功能

# -*- coding:UTF-8 -*-
"""
@author: dyy
@contact: douyaoyuan@126.com
@time: 2023/11/16 22:37
@file: ssh工具.py
@desc: 脚本提供了ssh登录,ssh文档上传,ssh文档下载,ssh公钥配置等功能,以及优良的用户体验
"""

# region 引入必要的依赖
import os
from enum import Enum
import json

模块名 = 'DebugInfo'
try:
    from DebugInfo.DebugInfo import *
except ImportError as impErr:
    print(f"尝试导入 {
     模块名} 依赖时检测到异常:{
     impErr}")
    print(f"尝试安装 {
     模块名} 模块:")
    try:
        os.system(f"pip install {
     模块名}")
    except OSError as osErr:
        print(f"尝试安装模块 {
     模块名} 时检测到异常:{
     osErr}")
        exit(0)
    else:
        try:
            from DebugInfo.DebugInfo import *
        except ImportError as impErr:
            print(f"再次尝试导入 {
     模块名} 依赖时检测到异常:{
     impErr}")
            exit(0)

模块名 = 'paramiko'
try:
    import paramiko
except ImportError as impErr:
    print(f"尝试导入 {
     模块名} 依赖时检测到异常:{
     impErr}")
    print(f"尝试安装 {
     模块名} 模块:")
    try:
        os.system(f"pip install {
     模块名}")
    except OSError as osErr:
        print(f"尝试安装模块 {
     模块名} 时检测到异常:{
     osErr}")
        exit(0)
    else:
        try:
            import paramiko
        except ImportError as impErr:
            print(f"再次尝试导入 {
     模块名} 依赖时检测到异常:{
     impErr}")
            exit(0)

模块名 = 'difflib'
try:
    import difflib  # 需要安装 difflib 模块,以支持字符差异对比操作
except ImportError as impErr:
    print(f"尝试导入 {
     模块名} 依赖时检测到异常:{
     impErr}")
    print(f"尝试安装 {
     模块名} 模块:")
    try:
        os.system(f"pip install {
     模块名}")
    except OSError as osErr:
        print(f"尝试安装模块 {
     模块名} 时检测到异常:{
     osErr}")
        exit(0)
    else:
        try:
            import difflib
        except ImportError as impErr:
            print(f"再次尝试导入 {
     模块名} 依赖时检测到异常:{
     impErr}")
            exit(0)


# endregion

# 定义一个 命令行参数类,用于解析和记录命令行参数
class 命令行参数类(入参基类):
    def __init__(self):
        super().__init__()
        self._添加参数('srcDir', str, '引用的路径')
        self._添加参数('srcDoc', str, '引用的文档')
        self._添加参数('everythingIP', str, 'everything HTTP 服务地址', '127.0.0.1')
        self._添加参数('everythingPort', str, 'everything HTTP 服务端口', '22')
        # 添加定制属性
        self.ssh接口列表: list[ssh接口类] = []

    # region 访问器
    @property
    def jsonCfg(self) -> str:
        if 'jsonCfg' in self._参数字典:
            return self._参数字典['jsonCfg'].else:
            return ''

    @jsonCfg.setter
    def jsonCfg(self,: str):
        if 'jsonCfg' in self._参数字典:
            self._参数字典['jsonCfg'].= str()

    @property
    def srcDir(self) -> str:
        if 'srcDir' in self._参数字典:
            return self._参数字典['srcDir'].else:
            return ''

    @srcDir.setter
    def srcDir(self,: str):
        if 'srcDir' in self._参数字典:
            self._参数字典['srcDir'].= str()

    @property
    def srcDoc(self) -> str:
        if 'srcDoc' in self._参数字典:
            return self._参数字典['srcDoc'].else:
            return ''

    @srcDoc.setter
    def srcDoc(self,: str):
        if 'srcDoc' in self._参数字典:
            self._参数字典['srcDoc'].= str()

    @property
    def everythingIP(self) -> str:
        if 'everythingIP' in self._参数字典:
            return self._参数字典['everythingIP'].else:
            return ''

    @everythingIP.setter
    def everythingIP(self,: str):
        if 'everythingIP' in self._参数字典:
            self._参数字典['everythingIP'].= str()

    @property
    def everythingPort(self) -> str:
        if 'everythingPort' in self._参数字典:
            return self._参数字典['everythingPort'].else:
            return ''

    @everythingPort.setter
    def everythingPort(self,: str):
        if 'everythingPort' in self._参数字典:
            self._参数字典['everythingPort'].= str()

    # endregion

    # region ssh候选列表
    def 解析Json(self,
                 jsonCfg: str = None,
                 encoding: str = 'utf-8',
                 画板: 打印模板 = None):
        """
                从指定的json文档中(如果不指定,则从 jsonCfg 参数指定的json文档中)读取配置参数,将值赋值给同名的命令行参数
                :param jsonCfg: 可以指定jsonCfg文档
                :param encoding: 可以指定jsonCfg文档的编码格式,默认为 utf-8
                :param 画板: 提供消息打印渠道
                :return: None
                """
        画板 = 画板 if isinstance(画板, 打印模板) else 打印模板()
        画板.执行位置(self.__class__, self.解析Json)

        if not jsonCfg:
            if 'jsonCfg' in self._参数字典.keys():
                jsonCfg = self._参数字典['jsonCfg'].值

        jsonCfg = str(jsonCfg if jsonCfg else '').strip()
        if not jsonCfg:
            画板.提示调试错误('jsonCfg 路径无效')
            return None
        if not os.path.isfile(jsonCfg):
            画板.提示调试错误(f'jsonCfg 不是有效的 json 文件路径: {
     jsonCfg}')
            return None
        if not jsonCfg.endswith('.json'):
            画板.提示调试错误(f'jsonCfg 不是 json 格式的文件: {
     jsonCfg}')

        画板.调试消息(f'待解析的 jsonCfg 文件是: {
     jsonCfg}')

        encoding = str(encoding if encoding else 'utf-8').strip()
        jsonDic: dict
        try:
            with open(jsonCfg, 'r', encoding=encoding) as f:
                jsonDic = json.load(f)
        except Exception as openExp:
            画板.提示调试错误(f'打开并读取 json 文档时遇到错误: {
     openExp}')
            jsonDic = {
   }
        if not jsonDic:
            画板.提示调试错误(f'未解析到有效的 json 内容: {
     jsonCfg}')
            return None

        jsonDic字典: dict = {
   }
        for,in jsonDic.items():
            # 去除键前后的空格= str().strip()
            if:
                jsonDic字典[] = 值

        已匹配的参数: dict[str, 入参基类._参数结构类] = {
   }
        未匹配的参数: dict[str, 入参基类._参数结构类] = {
   }
        for 参数 in self._参数字典.values():
            if 参数.名称 in jsonDic字典:
                参数.= jsonDic字典[参数.名称]
                if str(参数.).strip() == str(jsonDic字典[参数.名称]).strip():
                    已匹配的参数[参数.名称] = 参数
        if 'ssh接口列表' in jsonDic字典.keys() and jsonDic字典['ssh接口列表']:
            # 解析ssh接口配置
            ssh接口列表 = jsonDic字典['ssh接口列表']
            参数 = 命令行参数类._参数结构类(名称='ssh接口列表')
            参数.= ssh接口列表
            已匹配的参数['ssh接口列表'] = 参数
            for 接口 in ssh接口列表:
                ssh接口: ssh接口类 = ssh接口类()
                if '主机名称' in 接口:
                    ssh接口.主机名 = 接口['主机名称']
                if '主机地址' in 接口:
                    ssh接口.主机地址 = 接口['主机地址']
                if '端口号' in 接口:
                    ssh接口.端口号 = 接口['端口号']
                if '用户名' in 接口:
                    ssh接口.用户名 = 接口['用户名']
                if '密码' in 接口:
                    ssh接口.密码 = 接口['密码']
                self.ssh接口列表.append(ssh接口)
        for,in jsonDic字典.items():
            ifnot in 已匹配的参数.keys():
                这个参数: 入参基类._参数结构类 = 入参基类._参数结构类(名称=,
                                                                      类型=str,
                                                                      提示='这是 jsonCfg 中未匹配成功的参数',
                                                                      默认值=)
                未匹配的参数[] = 这个参数

        if 画板.正在调试 and (已匹配的参数 or 未匹配的参数):
            画板.准备表格()
            if 已匹配的参数:
                画板.添加一行('参数名', '参数类型', '参数值', '提示').修饰行(青字)
                for 参数 in 已匹配的参数.values():
                    画板.添加一行(参数.名称, 参数.类型, 参数., 参数.提示)
            if 未匹配的参数:
                画板.添加分隔行(提示文本='以下参数未匹配成功', 修饰方法=红字, 适应窗口=True)
                for 参数 in 未匹配的参数.values():
                    画板.添加一行(参数.名称, 参数.类型, 参数., 参数.提示)
            画板.展示表格()
    # endregion


class 文档操作记录类:
    def __init__(self,
                 旧文档: str = None,
                 新文档: str = None):
        self.__旧文档: str = 旧文档
        self.__新文档: str = 新文档
        self.__带标注的旧文档: str = ''
        self.__带标注的新文档: str = ''

    # region 访问器
    @property
    def 旧文档(self) -> str:
        return self.__旧文档

    @旧文档.setter
    def 旧文档(self, 文档: str):
        文档 = str(文档 if 文档 else '').strip()
        self.__旧文档 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1331123.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【hcie-cloud】【9】华为云Stack_Deploy部署工具介绍

文章目录 前言华为云Stack Deploy简介华为云Stack Deploy工具简介华为云Stack Deploy工具部署范围华为云Stack Deploy工具节点网络要求华为云Stack Deploy工具部署流程 华为云Stack Deploy功能介绍部署工具工程场景部署流程介绍创建工程 - 基本信息填写创建工程 - 基本参数选择…

【ITK库学习】使用itk库进行图像配准:“Hello World”配准

目录 1、itkImageRegistrationMethod / itkImageRegistrationMethodv42、itkTranslationTransform3、itkMeanSquaresImageToImageMetric / itkMeanSquaresImageToImageMetric44、itkRegularStepGradientDescentOptimizerv / itkRegularStepGradientDescentOptimizerv4 图像配准…

0基础学习VR全景平台篇第130篇:曝光三要素—感光度

上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 众所周知,摄影是一门用光的艺术。随着天气、地点、时间的变化,我们所处环境的光线也随之发生改变。而在不同的环境下该如何去正确的调节曝光,是…

Spring security之授权

前言 本篇为大家带来Spring security的授权,首先要理解一些概念,有关于:权限、角色、安全上下文、访问控制表达式、方法级安全性、访问决策管理器 一.授权的基本介绍 Spring Security 中的授权分为两种类型: 基于角色的授权&…

【Angular】Angular中的最差实践

自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…

4.4【共享源】克隆实战开发之截屏(二)

三,显示器截图 screen_read_display() 函数则用于捕获显示器的屏幕截图。我们需要在特权上下文中工作,以便可以完全访问系统的显示属性。我们可以通过调用具有 SCREEN_DISPLAY_MANAGER_CONTEXT 上下文类型的 screen_create_context() 来创建特权上下文。进程必须具有 root 的…

使用minio实现大文件断点续传

部署 minio 拉取镜像 docker pull minio/minio docker images新建映射目录 新建下面图片里的俩个目录 data(存放对象-实际的数据) config 存放配置开放对应端口 我使用的是腾讯服务器所以 在腾讯的安全页面开启 9000,9090 两个端口就可以了(根据大家实际…

使用python对windows/win11进行属性设置

有一个个人的需求,针对windows系统进行属性设置,这里以对鼠标的左右键主键进行切换为例,进行了研究,以当前win11系统为基础进行了更动。 首先是对于如果打开windows系统下的鼠标设置,有以下几种办法: 添加…

十大经典排序算法(个人总结C语言版)

文章目录 一、前言二、对比1.排序算法相关概念1.1 时间复杂度1.2 空间复杂度1.3 排序方式1.4 稳定度 2.表格比较3.算法推荐3.1 小规模数据3.2 中等规模数据3.3 大规模数据3.4 特殊需求 三、排序算法1.冒泡排序(Bubble Sort)1.1 简介1.2 示例代码&#xf…

使用互斥锁(Mutex)管理共享资源

在Go中确保并发安全性 并发是Go中的一个强大功能,它允许多个Goroutines(并发线程)同时执行。然而,伴随着强大的功能也带来了大量的责任。当多个Goroutines并发地访问和修改共享资源时,可能会导致数据损坏、数据竞争&a…

网络爬虫之Ajax动态数据采集

动态数据采集 规则 有时候我们在用 requests 抓取页面的时候,得到的结果可能和在浏览器中看到的不一样,在浏览器中可以看到正常显示的页面教据,但是使用 requests 得到的结果并没有,这是因为requests 获取的都是原始的 HTML 文档…

【小白攻略】php 小数转为百分比,保留两位小数的函数

php 小数转为百分比 首先,最简单直观的方法是利用PHP内置的number_format函数。该函数可以对一个数字进行格式化,并可以设置小数点后的精度。通过将小数乘以100,再用number_format函数将结果格式化为百分比形式,即可达到将小数转为…

uniapp怎么动态渲染导航栏的title?

直接在接口请求里面写入以下: 自己要什么参数就写什么参数 本人仅供参考: this.name res.data.data[i].name; console.log(名字, res.data.data[i].name); uni.setNavigationBarTitle({title: this.name}) 效果:

图论 | 网络流的基本概念

文章目录 流网路残留网络增广路径割最大流最小割定理最大流Edmonds-Karp 算法算法步骤程序代码时间复杂度 流网路 流网络: G ( V , E ) G (V, E) G(V,E) 有向图,不考虑反向边s:源点t:汇点 c ( u , v ) c(u, v) c(u,v)&#xff…

CSS:浮动

CSS:浮动 浮动效果浮动方式 float浮动特性标准流脱标脱标的影响脱标的影响范围 清除浮动清除浮动原理 clear基于clear的清除浮动方式额外标签法:afert伪元素法双伪元素法 清除浮动原理 BFCBFC定义BFC布局规则创建一个BFC基于BFC的清除浮动方式父级添加overflow法 浮…

物理模拟重力 斜抛运动计算 抛物线计算

物理模拟重力 斜抛运动计算 抛物线计算 一、介绍二、原理三、实现如下PhysicsUtil.cs 工具类Missile.cs 四、资源分享 一、介绍 模拟Unity原始重力系统进行重写,可是实现发射到指定目标位置并能继续当前力进行自身的弹力与摩擦继续运动 二、原理 将Unity原始不受控…

鸿蒙开发4.0-ArkTS与H5的交互

ArkTS侧与H5的交互 首先在开发H5页面(输入框和金额选择部分)前需要实现JSBridge桥接打通两侧的交互。开发者可以在ArkTS侧定义一个JSBridge类,在类中封装call方法以及initJsBridge方法。 准备异步执行脚本,在脚本中声明一个JSBri…

工具系列:PyCaret介绍_Fugue 集成_Spark、Dask分布式训练

工具系列:PyCaret介绍_Fugue 集成_Spark、Dask分布式训练 Fugue 是一个低代码的统一接口,用于不同的计算框架,如 Spark、Dask。PyCaret 使用 Fugue 来支持分布式计算场景。 目录 1、分布式计算示例: (1)分类 (2)回归 (3)时间…

7.5组合总和②(LC40-M)

算法: 相比于上一题,数组candidates有重复元素,而要求不能有重复的组合,所以相对于39.组合总和 (opens new window)难度提升了不少。 如何去重? 先把candidates排序,让重复的元素都在一起 单层递归时&a…

MATLAB - 读取双摆杆上的 IMU 数据

系列文章目录 前言 本示例展示了如何从安装在双摆杆上的两个 IMU 传感器生成惯性测量单元 (IMU) 读数。双摆使用 Simscape Multibody™ 进行建模。有关使用 Simscape Multibody™ 构建简易摆的分步示例,请参阅简易摆建模(Simscape Multibody&#xff09…