远程调用Linux shell 命令 并获取服务器的使用情况 - 工具类
引入jar包
<!-- linux链接,远程操作服务器-->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
工具类
package com.xx.common.utils.ssh;
import com.jcraft.jsch.*;
import com.nova.common.utils.Arith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
/**
* 远程调用Linux shell 命令
*
* @author wei.Li by 14-9-2.
*/
public class LinuxStateForShell {
private static final Logger LOGGER = LoggerFactory.getLogger(LinuxStateForShell.class);
public static final String CPU_MEM_SHELL = "top -b -n 1";
public static final String FILES_SHELL = "df -hl";
public static final String[] COMMANDS = {CPU_MEM_SHELL, FILES_SHELL};
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
private static Session session;
//SSH服务端口
private static final int REMOTE_PORT = 22;
//会话超时时间
private static final int SESSION_TIMEOUT = 10000;
//建立通讯超时时间
private static final int TIMEOUT = 1000;
//管道流超时时间(执行脚本超时时间)
private static final int CHANNEL_TIMEOUT = 5000;
public static void main(String[] args) {
//Map<String, String> result = runDistanceShell("root", "Xiexie123.", "152.67.5.187");
//String[] linux = disposeResultMessage(result);
//for (String l :linux){
// System.out.println(l);
//}
int status = runRemoteScript("152.67.5.187", "root", "xxx", "/usr/local/java/tomcat/logs/reload_tomcat.sh");
if (status == 0) {
System.out.println("脚本执行成功");
} else {
System.out.println("脚本执行失败");
}
}
/**
* @author: Wang excellence
* @date: 2021/7/1 15:09
* @Description: 获取远程服务器的的cpu占用率,内存使用率,磁盘状况
* 返回由数组返回 数组顺序为【0】cpu占用率,【1】内存使用率 【2】磁盘状况
*/
public static String[] disposeResultMessage(Map<String, String> result) {
String[] results = new String[3];
if (result == null) {
results = new String[]{"connect error !", "connect error !", "connect error !"};
return results;
}
for (String command : COMMANDS) {
String commandResult = result.get(command);
if (null == commandResult) {
continue;
}
if (command.equals(CPU_MEM_SHELL)) {
String[] strings = commandResult.split(LINE_SEPARATOR);
//将返回结果按换行符分割
for (String line : strings) {
line = line.toUpperCase();//转大写处理
//处理CPU Cpu(s): 10.8%us, 0.9%sy, 0.0%ni, 87.6%id, 0.7%wa, 0.0%hi, 0.0%si, 0.0%st
if (line.startsWith("%CPU(S):")) {
String cpuStr = "";
try {
cpuStr += line.split(":")[1].split(",")[0].replace("US", "");
cpuStr += "%";
} catch (Exception e) {
e.printStackTrace();
cpuStr += "计算过程出错";
}
results[0] = cpuStr.trim();
} else if (line.startsWith("KIB MEM")) {
//处理内存 Mem: 66100704k total, 65323404k used, 777300k free, 89940k buffers
try {
line = line.replace(" ", " ").replace(" ", " ");
String[] mems = line.split(" ");
double parseInt = Integer.parseInt(mems[7]);
double parseInt1 = Integer.parseInt(mems[3]);
//System.err.println("内存使率:" + (Arith.div(parseInt,parseInt1,4))*100 + "%");
results[1] = ((Arith.div(parseInt, parseInt1, 4)) * 100 + "%");
} catch (Exception e) {
e.printStackTrace();
results[1] = "计算过程出错";
continue;
}
}
}
} else if (command.equals(FILES_SHELL)) {
//处理系统磁盘状态
try {
results[2] = (disposeFilesSystem(commandResult)).replace(" ", "");
} catch (Exception e) {
e.printStackTrace();
results[2] = ("计算过程出错");
}
}
}
return results;
}
/**
* @author: Wang excellence
* @date: 2021/7/1 11:13
* @Description: REMOTE_HOST 远程主机IP, USERNAME 远程主机用户名, PASSWORD 远程主机密码, SHELLPATH 脚本名称及路径,与上文要对上
* 返回状态如果为0,则代表脚本被正确执行
*/
public static int runRemoteScript(String REMOTE_HOST, String USERNAME, String PASSWORD, String SHELLPATH) {
int result = 1;
Session jschSession = null;
try {
JSch jsch = new JSch();
//SSH授信客户端文件位置,一般是用户主目录下的.ssh/known_hosts
//jsch.setKnownHosts("D:\\known_hosts");
//jschSession.setConfig("StrictHostKeyChecking", "yes");
jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
jschSession.setConfig("StrictHostKeyChecking", "no");
// 密码认证
jschSession.setPassword(PASSWORD);
// 建立session
jschSession.connect(SESSION_TIMEOUT);
//建立可执行管道
ChannelExec channelExec = (ChannelExec) jschSession.openChannel("exec");
// 执行脚本命令"sh /root/hello.sh zimug"
channelExec.setCommand("sh " + SHELLPATH);
// 获取执行脚本可能出现的错误日志
channelExec.setErrStream(System.err);
//脚本执行结果输出,对于程序来说是输入流
InputStream in = channelExec.getInputStream();
// 5 秒执行管道超时
channelExec.connect(CHANNEL_TIMEOUT);
// 从远程主机读取输入流,获得脚本执行结果
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
//执行结果打印到程序控制台
//System.out.print(new String(tmp, 0, i));
}
if (channelExec.isClosed()) {
if (in.available() > 0) {
continue;
}
//获取退出状态,状态0表示脚本被正确执行
LOGGER.error("执行脚本操作:" + channelExec.getExitStatus());
//System.out.println("exit-status: "
// + channelExec.getExitStatus());
result = channelExec.getExitStatus();
break;
}
}
channelExec.disconnect();
} catch (JSchException | IOException e) {
e.printStackTrace();
} finally {
if (jschSession != null) {
jschSession.disconnect();
}
}
return result;
}
/**
* 连接到指定的HOST
*
* @return isConnect
* @throws JSchException JSchException
*/
public static boolean connect(String user, String passwd, String host) {
JSch jsch = new JSch();
try {
session = jsch.getSession(user, host, 22);
session.setPassword(passwd);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
//session.connect();
session.connect(TIMEOUT);
} catch (JSchException e) {
//e.printStackTrace();
//System.out.println("connect error !");
return false;
}
return true;
}
/**
* 远程连接Linux 服务器 执行相关的命令
*
* @param user 远程连接的用户名
* @param passwd 远程连接的密码
* @param host 远程连接的主机IP
* @return 最终命令返回信息
*/
public static Map<String, String> runDistanceShell(String user, String passwd, String host) {
String[] commands = COMMANDS;
if (!connect(user, passwd, host)) {
return null;
}
Map<String, String> map = new HashMap<>();
StringBuilder stringBuffer;
BufferedReader reader = null;
Channel channel = null;
try {
for (String command : commands) {
stringBuffer = new StringBuilder();
channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
channel.connect();
InputStream in = channel.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
String buf;
while ((buf = reader.readLine()) != null) {
//舍弃PID 进程信息
if (buf.contains("PID")) {
break;
}
stringBuffer.append(buf.trim()).append(LINE_SEPARATOR);
}
//每个命令存储自己返回数据-用于后续对返回数据进行处理
map.put(command, stringBuffer.toString());
}
} catch (IOException | JSchException e) {
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (channel != null) {
channel.disconnect();
}
session.disconnect();
}
return map;
}
//处理系统磁盘状态
/**
* Filesystem Size Used Avail Use% Mounted on
* /dev/sda3 442G 327G 93G 78% /
* tmpfs 32G 0 32G 0% /dev/shm
* /dev/sda1 788M 60M 689M 8% /boot
* /dev/md0 1.9T 483G 1.4T 26% /ezsonar
*
* @param commandResult 处理系统磁盘状态shell执行结果
* @return 处理后的结果
*/
private static String disposeFilesSystem(String commandResult) {
String[] strings = commandResult.split(LINE_SEPARATOR);
// final String PATTERN_TEMPLATE = "([a-zA-Z0-9%_/]*)\\s";
int size = 0;
int used = 0;
for (int i = 0; i < strings.length - 1; i++) {
if (i == 0) {
continue;
}
int temp = 0;
for (String s : strings[i].split("\\b")) {
if (temp == 0) {
temp++;
continue;
}
if (!s.trim().isEmpty()) {
if (temp == 1) {
size += disposeUnitG(s);
temp++;
} else {
used += disposeUnitG(s);
temp = 0;
}
}
}
}
return new StringBuilder().append("大小 ").append(size).append("G , 已使用").append(used).append("G ,空闲")
.append(size - used).append("G").toString();
}
/**
* 处理单位转换
* K/KB/M/T 最终转换为G 处理
*
* @param s 带单位的数据字符串
* @return 以G 为单位处理后的数值
*/
private static int disposeUnitG(String s) {
try {
s = s.toUpperCase();
String lastIndex = s.substring(s.length() - 1);
String num = s.substring(0, s.length() - 1);
int parseInt = Integer.parseInt(num);
if ("G".equals(lastIndex)) {
return parseInt;
} else if ("T".equals(lastIndex)) {
return parseInt * 1024;
} else if ("M".equals(lastIndex)) {
return parseInt / 1024;
} else if ("K".equals(lastIndex) || "KB".equals(lastIndex)) {
return parseInt / (1024 * 1024);
}
} catch (NumberFormatException e) {
e.printStackTrace();
return 0;
}
return 0;
}
}
欢迎一起来学习和指导,谢谢关注!
本文来自博客园,作者:xiexie0812,转载请注明原文链接:https://www.cnblogs.com/mask-xiexie/p/16087994.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了