|
@@ -1,5 +1,6 @@
|
|
|
package org.jeecg.modules.adweb.common.util;
|
|
|
|
|
|
+import ch.ethz.ssh2.ChannelCondition;
|
|
|
import ch.ethz.ssh2.Connection;
|
|
|
import ch.ethz.ssh2.Session;
|
|
|
import ch.ethz.ssh2.StreamGobbler;
|
|
@@ -9,6 +10,8 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
import java.io.*;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
|
|
|
/**
|
|
|
* 远程Shell执行工具类
|
|
@@ -262,27 +265,59 @@ public class ShellSSH2Util {
|
|
|
*/
|
|
|
private static String execmd(Connection connection, String cmd, StdoutListener listener) {
|
|
|
String result = "";
|
|
|
+ Session session = null;
|
|
|
try {
|
|
|
if (connection != null) {
|
|
|
- Session session = connection.openSession();// 打开一个会话
|
|
|
+ session = connection.openSession();// 打开一个会话
|
|
|
session.execCommand(cmd);// 执行命令
|
|
|
- result = processStdout(session.getStdout(), DEFAULT_CHART, listener);
|
|
|
- listener.stdout("命令标准输出结果:\n");
|
|
|
- listener.stdout(result);
|
|
|
- // 如果为得到标准输出为空,说明脚本执行出错了
|
|
|
- if (StringUtils.isBlank(result)) {
|
|
|
- listener.stderr("得到标准输出为空, 链接conn:" + connection + ",执行的命令:" + cmd);
|
|
|
- result = processStdout(session.getStderr(), DEFAULT_CHART, listener);
|
|
|
- listener.stderr("得到标准输出为空, 链接conn:" + connection + ",执行的命令:" + cmd + "; 错误信息:" + result);
|
|
|
- } else {
|
|
|
- listener.stdout("执行命令成功, 链接conn:" + connection + ",执行的命令:" + cmd);
|
|
|
+
|
|
|
+ // 使用线程池来管理输出读取线程
|
|
|
+ ExecutorService executorService = Executors.newFixedThreadPool(2);
|
|
|
+
|
|
|
+ // 读取标准输出
|
|
|
+ Session finalSession = session;
|
|
|
+ executorService.submit(() -> {
|
|
|
+ String stdoutResult = processStdout(finalSession.getStdout(), DEFAULT_CHART, listener);
|
|
|
+ listener.stdout("命令标准输出结果:\n");
|
|
|
+ listener.stdout(stdoutResult);
|
|
|
+ if (StringUtils.isBlank(stdoutResult)) {
|
|
|
+ listener.stderr("得到标准输出为空, 链接conn:" + connection + ",执行的命令:" + cmd);
|
|
|
+
|
|
|
+ listener.stderr("得到标准输出为空, 链接conn:" + connection + ",执行的命令:" + cmd + "; 错误信息:" + stdoutResult);
|
|
|
+ } else {
|
|
|
+ listener.stdout("执行命令成功, 链接conn:" + connection + ",执行的命令:" + cmd);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 读取标准错误
|
|
|
+ Session finalSession1 = session;
|
|
|
+ executorService.submit(() -> {
|
|
|
+ processStdout(finalSession1.getStderr(), DEFAULT_CHART, listener);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 等待所有输出读取线程完成
|
|
|
+ executorService.shutdown();
|
|
|
+ while (!executorService.isTerminated()) {
|
|
|
+ // 可以在这里设置一个超时,防止无限等待
|
|
|
+ Thread.sleep(300);
|
|
|
}
|
|
|
- session.close();
|
|
|
- connection.close();
|
|
|
+
|
|
|
+ // 等待脚本执行完毕
|
|
|
+ session.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EXIT_STATUS, 0);
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
listener.stderr("执行命令失败,链接conn:" + connection + ",执行的命令:" + cmd + " " + e);
|
|
|
log.error("执行命令失败,链接conn:{},执行的命令:{} {}", connection, cmd, e.getMessage());
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ } finally {
|
|
|
+ // 关闭会话和连接
|
|
|
+ if (session != null) {
|
|
|
+ session.close();
|
|
|
+ }
|
|
|
+ if (connection != null) {
|
|
|
+ connection.close();
|
|
|
+ }
|
|
|
}
|
|
|
return result;
|
|
|
|
|
@@ -298,22 +333,25 @@ public class ShellSSH2Util {
|
|
|
private static String processStdout(InputStream in, String charset, StdoutListener listener) {
|
|
|
InputStream stdout = new StreamGobbler(in);
|
|
|
StringBuffer buffer = new StringBuffer();
|
|
|
- try {
|
|
|
- BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
|
|
|
- String line = null;
|
|
|
+
|
|
|
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset))) {
|
|
|
+ String line;
|
|
|
+ StringBuilder bufferBuilder = new StringBuilder();
|
|
|
while ((line = br.readLine()) != null) {
|
|
|
- buffer.append(line + "\n");
|
|
|
- listener.stdout(line);
|
|
|
+ bufferBuilder.append(line).append("\n");
|
|
|
+ try {
|
|
|
+ listener.stdout(line);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 记录异常日志或进行其他处理
|
|
|
+ log.error("Error in listener.stdout: {}", e.getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
- br.close();
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- buffer.append("解析脚本出错:" + e.getMessage() + "\n");
|
|
|
- listener.stderr("解析脚本出错:" + e.getMessage());
|
|
|
- e.printStackTrace();
|
|
|
+ buffer.append(bufferBuilder);
|
|
|
} catch (IOException e) {
|
|
|
- buffer.append("解析脚本出错:" + e.getMessage() + "\n");
|
|
|
+ // 记录异常日志或进行其他处理
|
|
|
+ buffer.append("解析脚本出错:").append(e.getMessage()).append("\n");
|
|
|
listener.stderr("解析脚本出错:" + e.getMessage());
|
|
|
- e.printStackTrace();
|
|
|
+ log.error("解析脚本出错:{}", e.getMessage());
|
|
|
}
|
|
|
return buffer.toString();
|
|
|
}
|