使用java批量生成Xshell session(*.xsh)文件

背景

工作中需要管理多套环境, 有时需要同时登陆多个节点, 且每个环境用户名密码都一样, 因此需要一个方案来解决动态的批量登录问题.

XShell

Xshellsession管理功能:

  1. 提供了包括记住登录主机、用户名、密码及登录时执行命令或脚本(js,py,vbs)的功能

  2. session被存储在xsh文件中, 默认的存储在%USERPROFILE%\Documents\NetSarang Computer\7\Xshell\Sessions文件夹下

  3. 使用xshell可以直接打开存储在xsh文件中的用户登录信息, 比如: /d/Program_Files/Xshell/Xshell 192.168.31.6.xsh

  4. xsh文件使用UTF-16LE编码

  5. xsh采用与ini相同的格式进行配置

  6. xsh有许多配置项, 这里列举比较重要的:

    1. [CONNECTION].Host: 登录用户名

    2. [CONNECTION:AUTHENTICATION].UserName: 登录用户名

    3. [CONNECTION:AUTHENTICATION].Password: 登录密码, 使用XShell自有加解密算法, 因此在生成时需要先根据加解密算法生成加密后的密码, 参考how-does-Xmanager-encrypt-password1, 我通过pyinstaller -F XShellCryptoHelper.py将其打包为exejava使用

    4. [CONNECTION:AUTHENTICATION].UseInitScript: 是否使用登录脚本, 1表示开启, 0表示不使用

      XShell同时提供了与expect一样的交互功能, 可以和脚本共同使用, 但由于脚本本身具备这种功能, 并且移植性好, 所以本文不考虑expect

    5. [CONNECTION:AUTHENTICATION].ScriptPath: 登录脚本存储位置

需求

通过java生成一个/d/test.xsh文件(能生成一个就能生成N个), 并且在登录的同时执行一个python脚本, 效果如下:

在这里插入图片描述

所需信息:

  1. 用户名root

  2. 密码test@2023

  3. 登录主机192.168.31.6

  4. 执行脚本D:\init.py:

    def Main():# 等待root用户登录成功xsh.Screen.WaitForString('#')xsh.Screen.Send("echo hello word\r")
    

思路

XShell提供了一个默认的session配置文件: %USERPROFILE%\Documents\NetSarang Computer\7\Xshell\Sessions\default:

  1. 读取它, 并且根据关键字一一替换:
    1. Host= -> Host=192.168.31.6
    2. UserName= -> UserName=root
    3. Password= -> Password=xxx, 这里根据自己生成的密码密文进行替换
    4. UseInitScript=0 -> UseInitScript=1
    5. ScriptPath= -> ScriptPath=D:\init.py
  2. 使用UTF-16LE进行编码并保存在/d/test.xsh
  3. 使用XShell /d/test.xsh进行测试, 成功登录并且打印出hello world即可

实现

使用java17进行编码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;public class Xsh {private static final String XSHELL_CRYPTO_HELPER_LOCATION = "D:/XShellCryptoHelper.exe";private static final String[] ENCRYPT_CMD = new String[]{"cmd", "/c", XSHELL_CRYPTO_HELPER_LOCATION, "-e", "test@2023"};private static final String DEFAULT_SESSION_LOCATION = System.getenv("USERPROFILE") + "\\Documents\\NetSarang Computer\\7\\Xshell\\Sessions\\default";private static final String TEST_XSH_LOCATION = "D:\\test.xsh";private static final String[] RUN_XSHELL_CMD = new String[]{"cmd", "/k", "start D:\\Program_Files\\Xshell\\XShell.exe " + TEST_XSH_LOCATION};public static void main(String[] args) throws IOException, InterruptedException {String xshContent = Files.readAllLines(Paths.get(DEFAULT_SESSION_LOCATION), StandardCharsets.UTF_16LE).stream().map(line -> {if (line == null || line.isBlank()) {return line;}return switch (line.trim()) {case "Host=" -> "Host=192.168.31.6";case "UserName=" -> "UserName=root";case "Password=" -> "Password=" + encrypt();case "UseInitScript=0" -> "UseInitScript=1";case "ScriptPath=" -> "ScriptPath=D:\\init.py";default -> line;};}).collect(Collectors.joining(System.lineSeparator()));Path path = Paths.get(TEST_XSH_LOCATION);Files.deleteIfExists(path);Files.writeString(path, xshContent, StandardCharsets.UTF_16LE);CompletableFuture.runAsync(() -> {try {Runtime.getRuntime().exec(RUN_XSHELL_CMD);} catch (IOException e) {throw new RuntimeException(e);}});TimeUnit.SECONDS.sleep(3);}private static String encrypt() {InputStream is = null;InputStreamReader isr = null;BufferedReader br = null;try {Process process = Runtime.getRuntime().exec(ENCRYPT_CMD);process.waitFor();is = process.getInputStream();isr = new InputStreamReader(is);br = new BufferedReader(isr);// 只有一行输出return br.readLine();} catch (Exception e) {throw new RuntimeException(e);} finally {try {br.close();isr.close();is.close();} catch (IOException e) {throw new RuntimeException(e);}}}
}

参考

  1. Using Script

  1. 本项目原作者很长时间没有更新, 本来不支持7.*版本的加密, 我参考XDecrypt项目对其进行了补充, 当前已支持XShell全系列加解密!! ↩︎

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

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

相关文章

计算机组成学习-数据的表示和运算总结

1、进制与编码 1.1 进位计数法 常用的进位计数法有十进制、二进制、八进制、十六进制等。十六进制每个 数位可取0〜9、A、B、C、D、E、F中的任意一个,其中A、B、C、D、E、F分别表示 10〜15。 八进制数字通常以前缀 "0"(零)加上数…

GoLong的学习之路,进阶,RabbitMQ (消息队列)

快有一周没有写博客了。前面几天正在做项目。正好,项目中需要MQ(消息队列),这里我就补充一下我对mq的理解。其实在学习java中的时候,自己也仿照RabbitMQ自己实现了一个单机的mq,但是mq其中一个特点也就是&a…

基于ResNet18网络完成图像分类任务

目录 1 数据处理 1.1 数据集介绍 1.2 数据读取 1.3 构造Dataset类 2 模型构建 3 模型训练 4 模型评价 5 模型预测 6 什么是预训练模型和迁移学习 7 比较“使用预训练模型”和“不使用预训练模型”的效果。 总结 在本实践中,我们实践一个更通用的图像分类任务…

rust-flexi_logger

flexi_logger 是字节开源的rust日志库。目前有log4rs、env_log 等库,综合比较下来,还是flexi_logger简单容易上手,而且自定义很方便,以及在效率方面感觉也会高,下篇文章我们来测试下。 下面来看下怎么使用 关注 vx gol…

探索未来能源:可控核聚变的挑战与希望

探索未来能源:可控核聚变的挑战与希望 引言 随着人类社会的不断发展,对能源的需求也在持续增长。传统的化石燃料能源在燃烧过程中会产生大量的二氧化碳和其他温室气体,导致全球气候变暖,对环境产生了重大威胁。因此,寻找一种清洁、可持续、高效的能源成为了当务之急。在…

Redis hash表源码解析

整体数据结构:链式hash解决hash冲突、采用渐进式hash来完成扩容过程。 /** 哈希表节点*/ typedef struct dictEntry {// 键void *key;// 值union {void *val;uint64_t u64;int64_t s64;} v;// 指向下个哈希表节点,形成链表struct dictEntry *next;} dict…

ubuntu22.04离线手动安装openstack yoga和ceph quincy

目录 写在前面材料准备一. OpenStack部1. 创建虚拟网络和虚拟机2. 配置离线环境3. 环境准备3.1 配置网络3.2 配置主机名并配置解析3.3 时间调整3.4 安装openstack客户端3.5 安装部署MariaDB3.6 安装部署RabbitMQ控制节点操作3.7 安装部署Memcache控制节点操作 4. 部署配置keyst…

TwinCAT3一个PLC设备里多个程序工程之间通讯

目录 1、创建TwinCAT3工程,再分别创建两个PLC程序工程 2、PLC1工程中添加如下代码,然后编译重新生成PLC1工程 3、PLC2工程中添加如下代码,然后编译重新生成PLC2工程 4、变量关联 5、一个PLC运行多个PLC工程设置 7、工程下载链接 1、创建…

配置中心--Spring Cloud Config

目录 概述 环境说明 步骤 创建远端git仓库 准备配置文件 配置中心--服务端 配置中心--客户端 配置中心的高可用 配置中心--服务端 配置中心--客户端 消息总线刷新配置 配置中心--服务端 配置中心--客户端 概述 因为微服务架构有很多个服务,手动一个一…

wireshark自定义协议插件开发

目录 脚本代码 报文显示 脚本代码 local NAME "test" test_proto Proto("test", "test Protocol") task_id ProtoField.uint16("test.task_id", "test id", base.DEC) cn ProtoField.uint8("test.cn", &qu…

【Java 基础】15 注解

文章目录 1.什么是注解2.元注解1)定义2)分类 3.内置注解4.自定义注解5.注解的基本语法6.验证注解是否生效7.注解的使用场景8.注解的注意事项结语 1.什么是注解 注解(Annotation)可以理解成一种特殊的 “注释” 注解定义时以 符号…

多线程06 单例模式,阻塞队列以及模拟实现

前言 上篇文章我们讲了wait和notify两个方法的使用.至此,多线程的一些基本操作就已经结束了,今天我们来谈谈多线程的一些简单应用场景. 单例模式 单例模式,顾名思义,只有一个实例的模式,我们有两种实现方式,分别是懒汉式和饿汉式,我们来分别给出代码. 饿汉式(此处的饿表示创建实…

详解Spring中的Aop编程原理JDK动态代理和CGLIB动态代理

😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783…

yolov8模型 onnxruntime推理及可视化

参考:https://github.com/ultralytics/ultralytics/blob/main/examples/YOLOv8-ONNXRuntime/main.py 1、yolov8 onnxruntime推理代码 1)导出参考:https://blog.csdn.net/weixin_42357472/article/details/131412851 2)查看保存的模型onnx的输入格式等信息 登录https://n…

使用PCReg.PyTorch项目训练自己的数据集进行点云配准

项目地址: https://github.com/zhulf0804/PCReg.PyTorch/tree/main 网络简介: 网络是基于PointNet Concat FC的,它没有其它复杂的结构,易于复现。因其简洁性,这里暂且把其称作点云配准的Benchmark。因作者源码中复杂…

剑指 Offer(第2版)面试题 14:剪绳子

剑指 Offer(第2版)面试题 14:剪绳子 剑指 Offer(第2版)面试题 14:剪绳子解法1:动态规划解法2:数学 剑指 Offer(第2版)面试题 14:剪绳子 题目来源…

DOM 事件的注册和移除

前端面试大全DOM 事件的注册和移除 🌟经典真题 🌟DOM 注册事件 HTML 元素中注册事件 DOM0 级方式注册事件 DOM2 级方式注册事件 🌟DOM 移除事件 🌟真题解答 🌟总结 🌟经典真题 总结一下 DOM 中如何…

TCP连接为什么是三次握手,而不是两次和四次

答案 阻止重复的历史连接同步初始序列号避免资源浪费 原因 阻止重复的历史连接(首要原因) 考虑这样一种情况: 客户端现在要给服务端建立连接,向服务端发送了一个SYN报文段(第一次握手),以表示请…

固定Microsoft Edge浏览器的位置设置,避免自动回调至中国

问题描述 在使用Copilot等功能时,需要将Microsoft Edge浏览器的位置设置为国外。但每次重新打开浏览器后,位置设置又自动回调至中国,导致每次均需要手动调整。 原因分析 这个问题的出现是因为每次启动Microsoft Edge时,默认打开…

cmake和vscode 下的cmake的使用详解(三)

第七讲:【实战】使用 VSCode 进行完整项目开发 案例:士兵突击 需求: 1. 士兵 许三多 有一把 枪 ,叫做 AK47 2. 士兵 可以 开火 3. 士兵 可以 给枪装填子弹 4. 枪 能够 发射 子弹 5. 枪 能够 装填子弹 ——…