背景
工作中需要管理多套环境, 有时需要同时登陆多个节点, 且每个环境用户名密码都一样, 因此需要一个方案来解决动态的批量登录问题.
XShell
-
session
被存储在xsh
文件中, 默认的存储在%USERPROFILE%DocumentsNetSarang Computer7XshellSessions
文件夹下 -
使用
xshell
可以直接打开存储在xsh
文件中的用户登录信息, 比如:/d/Program_Files/Xshell/Xshell 192.168.31.6.xsh
-
-
[CONNECTION:AUTHENTICATION].Password
: 登录密码, 使用XShell
自有加解密算法, 因此在生成时需要先根据加解密算法生成加密后的密码, 参考how-does-Xmanager-encrypt-password1, 我通过pyinstaller -F XShellCryptoHelper.py
将其打包为exe
供java
使用 -
[CONNECTION:AUTHENTICATION].UseInitScript
: 是否使用登录脚本, 1表示开启, 0表示不使用XShell
同时提供了与expect
一样的交互功能, 可以和脚本共同使用, 但由于脚本本身具备这种功能, 并且移植性好, 所以本文不考虑expect
需求
通过java
生成一个/d/test.xsh
文件(能生成一个就能生成N
个), 并且在登录的同时执行一个python
脚本, 效果如下:
所需信息:
-
用户名
root
-
密码
test@2023
-
登录主机
192.168.31.6
-
def Main(): # 等待root用户登录成功 xsh.Screen.WaitForString('#') xsh.Screen.Send("echo hello wordr")
思路
XShell
提供了一个默认的session
配置文件: %USERPROFILE%DocumentsNetSarang Computer7XshellSessionsdefault
:
实现
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);
}
}
}
}
参考
原文地址:https://blog.csdn.net/Young4Dream/article/details/134760344
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_32328.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!