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

此文分享一个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.__旧文档 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达RLHF课程笔记

1.创建偏好数据集 一个prompt输入到LLM后可以有多个回答,对每个回答选择偏好 比如{prompt,answer1,answer2,prefer1} 2.根据这个数据集(偏好数据集),创建reward model,这个model也是一个LLM,并且它是回归模型&#…

C语言之指针

目录 函数的参数 对象和地址 取地址运算符 注意 指针 注意 指针运算符 注意 在C语言中,指针是一个十分重要的概念,它的作用是“指示对象”。 例如:你要去一座公寓楼找一位朋友,公寓楼由很多楼层组成,每个楼层…

解决 MATLAB 遗传算法中 exitflg=4 的问题

一、优化问题简介 以求解下述优化问题为例: P 1 : min ⁡ p ∑ k 1 K p k s . t . { ∑ k 1 K R k r e q l o g ( 1 α k ∗ p k ) ≤ B b s , ∀ k ∈ K p k ≥ 0 , ∀ k ∈ K \begin{align} {P_1:}&\mathop{\min}_{\bm{p}}{ \sum\limits_{k1}^K p_k } \no…

【Linux笔记】文件查看和编辑

🍎个人博客:个人主页 🏆个人专栏:Linux学习 ⛳️ 功不唐捐,玉汝于成 目录 前言 命令 cat (Concatenate and Display): more 和 less: nano 和 vim (文本编辑器): 结语 我的其他博客 前言 学习Linux命令行和文件…

1854_bash中利用管道进行批量参数传递以及由此实现简单的代码行数统计

Grey 全部学习内容汇总: GreyZhang/bash_basic: my learning note about bash shell. (github.com) 1854_bash中的参数传递以及利用bash进行简单的代码行数统计 有时候需要处理多个文件,把每一个文件作为参数传递给某一个程序。这时候可以用到 xargs&…

高频知识汇总 | 【操作系统】面试题汇总(万字长博通俗易懂)

前言 这篇我亲手整理的【操作系统】资料,融入了我个人的理解。当初我在研习八股文时,深感复习时的困扰,网上资料虽多,却过于繁杂,有的甚至冗余。例如,文件管理这部分,在实际面试中很少涉及&…

Ai图片处理

Ai也可以直接导入PS文件,只不过需要进行一个相关的选择,一般来说是将图层转化为对象 第二个为图层拼合为单个图像(不常用) 第三个则是将隐藏的图片也进行显示 如果你觉得图片的信息的过少好想插入其他的图片,可以选择…

认识Linux背景

1.发展史 Linux从哪里来?它是怎么发展的?在这里简要介绍Linux的发展史 要说Linux,还得从UNIX说起 UNIX发展的历史 1968年,一些来自通用电器公司、贝尔实验室和麻省理工学院的研究人员开发了一个名叫Multics的特殊操作系统。Mu…

BDD - Python Behave Tags 过滤

BDD - Python Behave Tags 过滤 引言实例创建 feature 文件创建 step 实现 Tag 过滤执行执行单个标签 --tagstagname执行多个标签 OR 关系 --tagstag1,tag2多个标签 AND 关系 --tagstag1 --tagstag2单标签非关系 --tags ~tagname 引言 随着项目进展,QA 创建的 Beh…

【JMeter】使用BeanShell写入内容到文件

一、前言 ​ 在我们日常工作中,可能会遇到需要将请求返回的数据写入到文件中。在我们使用JMeter进行性能测试时,就经常能够遇到这种情况。要想达到这种目的,我们一般采取BeanShell后置处理器来将内容写入到文件。 二、提取 ​ 在目前大多数的…

记一次 Nginx 调参的踩坑经历

最近在基于SSE(Server Sent Events)做服务端单向推送服务,本地开发时一切顺利,但是在部署到预发环境时就碰到1个很诡异的问题,这里需要简单介绍下我们的整体架构: 整体架构 可以看到所有的请求都会先到统一…

2. 结构型模式 - 桥接模式

亦称: Bridge 意图 桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用 问题 抽象? 实现? 听上去挺吓人? 让我们慢慢来&#x…

2023年软件测试已经崩盘了吗?为什么很难找到工作?

最近后台很多粉丝给我留言: 2023年软件测试已经崩盘了吗,为什么都找不到工作了? 确实,今年经济大环境不好,企业也都在降本增效,如果技术能力还在被应届生竞争岗位的阶段,只会越来越难。 找不…

3d max高质量渲染时,硬件的要求有什么?

渲染过程中,想要追求,效果图高质量渲染,高效率渲染的过程中,3d max高清渲染不只是三维软件的一个要求,对于本地计算机的硬件要求配置也是很重要的。 今天,小编带大家来聊聊3d max高质量渲染过程中&#xff…

20 Vue3中使用v-for遍历普通数组

概述 使用v-for遍历普通数组在真实开发中还是比较常见的。 基本用法 我们创建src/components/Demo20.vue&#xff0c;代码如下&#xff1a; <script setup> const tags ["JavaScript", "Vue3", "前端"] </script> <template…

单例模式实现

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 单例模式 1. 什么是单例模式2. 饿汉模式3.…

机器学习的一些有趣的点【异常检测】

机器能不能知道自己不知道&#xff0c;而不是给出判断中的一种&#xff1f; Classifier&#xff08;分类&#xff09;Anomaly Detection&#xff08;异常检测&#xff09; 机器能不能说出为什么知道&#xff1f; 有时候可能是因为数据的问题导致了这种错觉。 机器学习是否会有错…

虾皮跨境电商的收款方式及选择指南

虾皮&#xff08;Shopee&#xff09;作为一家知名的跨境电商平台&#xff0c;为卖家提供了多种收款方式&#xff0c;以满足不同卖家的需求。本文将介绍虾皮跨境电商平台的主要收款方式&#xff0c;并提供选择指南&#xff0c;帮助卖家根据自身需求和目标市场选择最合适的收款方…

机器学习---K近邻算法

1. KNN算法 K近邻算法&#xff0c;即K-Nearest Neighbor algorithm&#xff0c;简称KNN算法&#xff0c;是一个理论上比较成熟的方法&#xff0c;也 是最简单的机器学习算法之一&#xff0c;1968年由 Cover 和 Hart 提出。 该方法的思路是&#xff1a;如果一个样本在特征空间…

人工智能中GAN 的五大有趣应用

引言 你能看出这张照片中面部的共同点吗&#xff1f; 这些人都不是真实存在的&#xff01;这些面部图像都是由 GAN 技术生成的。 “GAN” 这个词是由 Ian Goodfellow 在 2014 年提出的&#xff0c;但相关概念早在 1990 年就存在了&#xff08;Jrgen Schmidhuber 开创&#xf…