Compare commits
No commits in common. "supercomputing" and "master" have entirely different histories.
supercompu
...
master
6
pom.xml
6
pom.xml
|
|
@ -143,11 +143,7 @@
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.hutool</groupId>
|
|
||||||
<artifactId>hutool-all</artifactId>
|
|
||||||
<version>5.7.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package net.educoder.bridge.common.model;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* shell执行结果
|
|
||||||
*
|
|
||||||
* @author 威少
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class CmdResult {
|
|
||||||
/**
|
|
||||||
* 退出码
|
|
||||||
*/
|
|
||||||
private Integer exitStatus;
|
|
||||||
/**
|
|
||||||
* 实际输出
|
|
||||||
*/
|
|
||||||
private String out;
|
|
||||||
|
|
||||||
public enum ExitStatus {
|
|
||||||
/**
|
|
||||||
* 成功
|
|
||||||
*/
|
|
||||||
SUCCESS(0),
|
|
||||||
/**
|
|
||||||
* 超时
|
|
||||||
*/
|
|
||||||
TIMEOUT(124),
|
|
||||||
/**
|
|
||||||
* 默认失败
|
|
||||||
*/
|
|
||||||
FAIL(-1);
|
|
||||||
|
|
||||||
private final int code;
|
|
||||||
ExitStatus(int code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package net.educoder.bridge.webssh.controller;
|
|
||||||
|
|
||||||
import net.educoder.bridge.common.model.ApiResult;
|
|
||||||
import net.educoder.bridge.webssh.service.JchService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/ssh")
|
|
||||||
public class SshController {
|
|
||||||
@Autowired
|
|
||||||
private JchService jchService;
|
|
||||||
|
|
||||||
@GetMapping("/exec")
|
|
||||||
public ApiResult<String> exec(String cmd,String username,String secret,String host,Integer port) throws Exception {
|
|
||||||
ApiResult<String> r = new ApiResult<>();
|
|
||||||
String s = jchService.sshCommand(host, port, username, secret, cmd);
|
|
||||||
r.setMsg("success");
|
|
||||||
r.setData(s);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
package net.educoder.bridge.webssh.controller;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.educoder.bridge.common.model.ApiResult;
|
|
||||||
import net.educoder.bridge.common.model.CmdResult;
|
|
||||||
import net.educoder.bridge.webssh.service.WinService;
|
|
||||||
import net.educoder.bridge.webssh.utils.CmdUtil;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在windows操作
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/win")
|
|
||||||
public class WinController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WinService winService;
|
|
||||||
|
|
||||||
@GetMapping("/exec")
|
|
||||||
public ApiResult<String> exec(String cmd){
|
|
||||||
log.info("win exec cmd:{}",cmd);
|
|
||||||
ApiResult<String> r = new ApiResult<>();
|
|
||||||
|
|
||||||
CmdResult result = CmdUtil.executeAndGetExitStatus(cmd);
|
|
||||||
|
|
||||||
r.setCode(result.getExitStatus());
|
|
||||||
r.setMsg(result.getOut());
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/remote/upload")
|
|
||||||
public ApiResult<String> uploadFile(@RequestParam("file") MultipartFile file, String tpiId, String remoteTargetDir, String username, String secret, String host, Integer port) {
|
|
||||||
log.info("win upload file to ssh--tpiId:{}",tpiId);
|
|
||||||
ApiResult<String> r = new ApiResult<>();
|
|
||||||
r.setCode(0);
|
|
||||||
r.setMsg("success");
|
|
||||||
|
|
||||||
if (null!=file){
|
|
||||||
log.info("***uploadFile filename:{}; size:{}" ,file.getOriginalFilename(),file.getSize());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
winService.uploadFileToSsh(tpiId,file,remoteTargetDir,username,secret,host,port);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("win upload file to ssh ERROR--tpiId:{}; e:{}",tpiId,e);
|
|
||||||
r.setCode(500);
|
|
||||||
r.setMsg("error");
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/remote/download")
|
|
||||||
public void downloadFile(String tpiId, String remoteSrcDir , String username, String secret, String host, Integer port, HttpServletResponse response) {
|
|
||||||
log.info("win download file by ssh--tpiId:{}",tpiId);
|
|
||||||
File zipDir = null;
|
|
||||||
try {
|
|
||||||
zipDir = winService.downloadFileDir(tpiId,remoteSrcDir,username,secret,host,port);
|
|
||||||
String fileName = zipDir.getName();
|
|
||||||
response.setCharacterEncoding("utf-8");
|
|
||||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
|
|
||||||
response.setContentType("application/zip");
|
|
||||||
try (FileInputStream fileInputStream = new FileInputStream(zipDir);
|
|
||||||
OutputStream outputStream = response.getOutputStream()) {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
|
|
||||||
|
|
||||||
outputStream.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
outputStream.flush();
|
|
||||||
}
|
|
||||||
}catch (Exception e){
|
|
||||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
|
||||||
log.error("win download file by ssh ERROR--tpiId:{}; e:{}",tpiId,e);
|
|
||||||
}finally {
|
|
||||||
if (zipDir!=null && zipDir.exists()){
|
|
||||||
zipDir.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,6 @@ package net.educoder.bridge.webssh.service;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
@ -11,9 +10,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import com.jcraft.jsch.*;
|
|
||||||
import net.educoder.bridge.webssh.utils.AESEncryptionUtil;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -22,6 +18,10 @@ import org.springframework.web.socket.TextMessage;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.jcraft.jsch.ChannelShell;
|
||||||
|
import com.jcraft.jsch.JSch;
|
||||||
|
import com.jcraft.jsch.Session;
|
||||||
|
import com.jcraft.jsch.UserInfo;
|
||||||
|
|
||||||
import net.educoder.bridge.webssh.model.ConnectInfo;
|
import net.educoder.bridge.webssh.model.ConnectInfo;
|
||||||
import net.educoder.bridge.webssh.model.WebscoketObj;
|
import net.educoder.bridge.webssh.model.WebscoketObj;
|
||||||
|
|
@ -77,16 +77,6 @@ public class JchService {
|
||||||
JSONObject object = JSONObject.parseObject(buffer);
|
JSONObject object = JSONObject.parseObject(buffer);
|
||||||
String tp = object.getString("tp");
|
String tp = object.getString("tp");
|
||||||
if ("init".equals(tp)) {
|
if ("init".equals(tp)) {
|
||||||
// 先将ssh信息解密,放入原json。
|
|
||||||
JSONObject jsonData =object.getJSONObject("data");
|
|
||||||
JSONObject sshinfo = JSONObject.parseObject(AESEncryptionUtil.decrypt(jsonData.getString("ssh_info")));
|
|
||||||
if (sshinfo!=null){
|
|
||||||
jsonData.put("host",sshinfo.getString("host"));
|
|
||||||
jsonData.put("port",sshinfo.getString("port"));
|
|
||||||
jsonData.put("username",sshinfo.getString("username"));
|
|
||||||
jsonData.put("secret",sshinfo.getString("secret"));
|
|
||||||
}
|
|
||||||
logger.info("** ws_jsonData **:"+jsonData);
|
|
||||||
// 初始化连接
|
// 初始化连接
|
||||||
// {"tp":"init","data":{"host":"106.75.96.108","port":"41080","username":"root","secret":"123123","myshixun_id":"1080","rows":"30"}}
|
// {"tp":"init","data":{"host":"106.75.96.108","port":"41080","username":"root","secret":"123123","myshixun_id":"1080","rows":"30"}}
|
||||||
ConnectInfo connectInfo = object.getObject("data", ConnectInfo.class);
|
ConnectInfo connectInfo = object.getObject("data", ConnectInfo.class);
|
||||||
|
|
@ -320,29 +310,4 @@ public class JchService {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接操作机,执行命令
|
|
||||||
*/
|
|
||||||
public String sshCommand(String host, int port, String username, String password, String command) throws JSchException, IOException {
|
|
||||||
JSch jsch = new JSch();
|
|
||||||
Session session = jsch.getSession(username, host, port);
|
|
||||||
//避免SSH 的公钥检查
|
|
||||||
session.setConfig("StrictHostKeyChecking", "no");
|
|
||||||
session.setPassword(password);
|
|
||||||
session.connect();
|
|
||||||
|
|
||||||
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
|
|
||||||
InputStream in = channelExec.getInputStream();
|
|
||||||
channelExec.setCommand(command);
|
|
||||||
channelExec.setErrStream(System.err);
|
|
||||||
channelExec.connect();
|
|
||||||
String out = IOUtils.toString(in, StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
in.close();
|
|
||||||
channelExec.disconnect();
|
|
||||||
session.disconnect();
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
package net.educoder.bridge.webssh.service;
|
|
||||||
|
|
||||||
import com.jcraft.jsch.*;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.educoder.bridge.webssh.utils.CmdUtil;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jshixiong
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class WinService {
|
|
||||||
public static final String WINDOWS_WORKSPACE = "C:\\data\\workspace\\";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传目标路径
|
|
||||||
*/
|
|
||||||
private static final String FILE_OP_DESTINATION = "userfiles";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件下载目录路径
|
|
||||||
*/
|
|
||||||
private static final String FILE_DL_DESTINATION = "downloadfiles";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件到远程目录
|
|
||||||
*
|
|
||||||
* @param tpiId tpiId
|
|
||||||
* @param file 上传的文件
|
|
||||||
* @param remoteTargetDir 远程文件夹
|
|
||||||
*/
|
|
||||||
public void uploadFileToSsh(String tpiId, MultipartFile file, String remoteTargetDir , String username, String secret, String host, Integer port) throws Exception {
|
|
||||||
String localFileDir = WINDOWS_WORKSPACE + tpiId + File.separator + FILE_OP_DESTINATION;
|
|
||||||
CmdUtil.executeAndGetExitStatus("mkdir " + localFileDir);
|
|
||||||
//文件windows放本地
|
|
||||||
File localFile = new File(localFileDir + File.separator + file.getOriginalFilename());
|
|
||||||
FileUtils.copyInputStreamToFile(file.getInputStream(),localFile);
|
|
||||||
|
|
||||||
JSch jsch = new JSch();
|
|
||||||
Session session = jsch.getSession(username, host, port);
|
|
||||||
session.setPassword(secret);
|
|
||||||
session.setConfig("StrictHostKeyChecking", "no");
|
|
||||||
session.connect();
|
|
||||||
//创建远程文件夹
|
|
||||||
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
|
|
||||||
channelExec.setCommand("mkdir -p " + remoteTargetDir);
|
|
||||||
channelExec.connect();
|
|
||||||
//上传
|
|
||||||
log.info("uploadFileToSsh: {}==>{}",localFile.getAbsolutePath(),remoteTargetDir + "/" + file.getOriginalFilename());
|
|
||||||
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
|
|
||||||
channelSftp.connect();
|
|
||||||
channelSftp.put(localFile.getAbsolutePath(), remoteTargetDir + "/" + file.getOriginalFilename());
|
|
||||||
|
|
||||||
channelExec.disconnect();
|
|
||||||
channelSftp.disconnect();
|
|
||||||
session.disconnect();
|
|
||||||
//删除windows存放的文件
|
|
||||||
CmdUtil.executeAndGetExitStatus("rmdir /s /q " + localFileDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将远程文件夹打包下载到windows工作目录
|
|
||||||
*
|
|
||||||
* @param tpiId tpiId
|
|
||||||
* @param remoteSrcDir 需下载的远程文件夹
|
|
||||||
*/
|
|
||||||
public File downloadFileDir(String tpiId, String remoteSrcDir , String username, String secret, String host, Integer port) throws Exception {
|
|
||||||
String localFileDir = WINDOWS_WORKSPACE + tpiId + File.separator + FILE_DL_DESTINATION;
|
|
||||||
CmdUtil.executeAndGetExitStatus("mkdir " + localFileDir);
|
|
||||||
//从ssh远程下载所有文件到windows
|
|
||||||
JSch jsch = new JSch();
|
|
||||||
Session session = jsch.getSession(username, host, port);
|
|
||||||
session.setPassword(secret);
|
|
||||||
session.setConfig("StrictHostKeyChecking", "no");
|
|
||||||
session.connect();
|
|
||||||
//远程打包
|
|
||||||
String zipFile = remoteSrcDir + ".zip";
|
|
||||||
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
|
|
||||||
InputStream in = channelExec.getInputStream();
|
|
||||||
channelExec.setCommand("cd " + remoteSrcDir + " && rm -rf " + zipFile + " && zip -qr " + zipFile + " .");
|
|
||||||
channelExec.connect();
|
|
||||||
String out = IOUtils.toString(in, StandardCharsets.UTF_8);
|
|
||||||
log.info("打包=={}",out);
|
|
||||||
//获取远程zip文件
|
|
||||||
String localZipFile = localFileDir + File.separator + zipFile.substring(zipFile.lastIndexOf("/")+1);
|
|
||||||
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
|
|
||||||
channelSftp.connect();
|
|
||||||
channelSftp.get(zipFile, localZipFile);
|
|
||||||
|
|
||||||
//关闭连接
|
|
||||||
in.close();
|
|
||||||
channelExec.disconnect();
|
|
||||||
channelSftp.disconnect();
|
|
||||||
session.disconnect();
|
|
||||||
//打包文件夹
|
|
||||||
return new File(localZipFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
package net.educoder.bridge.webssh.utils;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AES对称加密
|
|
||||||
* @author jshixiong
|
|
||||||
*/
|
|
||||||
public class AESEncryptionUtil {
|
|
||||||
private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";
|
|
||||||
/**
|
|
||||||
* 16位key
|
|
||||||
*/
|
|
||||||
private static final String ENCRYPTION_KEY = "MyKey@zq12345678";
|
|
||||||
/**
|
|
||||||
* 16位IV
|
|
||||||
*/
|
|
||||||
private static final String INIT_VECTOR = "MyIV@zq123456789";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AES加密
|
|
||||||
*/
|
|
||||||
public static String encrypt(String message) {
|
|
||||||
try {
|
|
||||||
IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes(StandardCharsets.UTF_8));
|
|
||||||
SecretKeySpec secretKeySpec = new SecretKeySpec((ENCRYPTION_KEY).getBytes(StandardCharsets.UTF_8), "AES");
|
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv);
|
|
||||||
|
|
||||||
byte[] encryptedBytes = cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
|
|
||||||
return Base64.getEncoder().encodeToString(encryptedBytes);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AES解密
|
|
||||||
*/
|
|
||||||
public static String decrypt(String encryptedMessage) {
|
|
||||||
try {
|
|
||||||
IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes(StandardCharsets.UTF_8));
|
|
||||||
SecretKeySpec secretKeySpec = new SecretKeySpec((ENCRYPTION_KEY).getBytes(StandardCharsets.UTF_8), "AES");
|
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv);
|
|
||||||
|
|
||||||
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedMessage);
|
|
||||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
|
||||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
package net.educoder.bridge.webssh.utils;
|
|
||||||
|
|
||||||
import net.educoder.bridge.common.model.CmdResult;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* windows命令行工具
|
|
||||||
* @author jshixiong
|
|
||||||
*/
|
|
||||||
public class CmdUtil {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CmdUtil.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行cmd命令并获取输出
|
|
||||||
*/
|
|
||||||
public static String execute(String command) {
|
|
||||||
return executeAndGetExitStatus(command).getOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行cmd命令并获得输出及退出码,失败重试 共尝试retryTimes次
|
|
||||||
*/
|
|
||||||
public static CmdResult executeAndGetExitStatus(String command, int retryTimes) {
|
|
||||||
CmdResult result = new CmdResult();
|
|
||||||
|
|
||||||
for (int i = 0; i < retryTimes; i++) {
|
|
||||||
result = executeAndGetExitStatus(command);
|
|
||||||
if (result.getExitStatus() != 0) {
|
|
||||||
logger.info("执行cmd错误, 再次执行 command: {}, result: {}, times: {}", command, result, i);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行命令并获得输出以及退出码
|
|
||||||
*/
|
|
||||||
public static CmdResult executeAndGetExitStatus(String command) {
|
|
||||||
CmdResult result = new CmdResult();
|
|
||||||
|
|
||||||
StringBuilder out = new StringBuilder();
|
|
||||||
Integer exitStatus = -1;
|
|
||||||
|
|
||||||
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", command);
|
|
||||||
pb.redirectErrorStream(true);
|
|
||||||
try {
|
|
||||||
Process process = pb.start();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
out.append(line);
|
|
||||||
out.append(System.getProperty("line.separator"));
|
|
||||||
}
|
|
||||||
exitStatus = process.waitFor();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("执行cmd出错, command:{}", command, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.setOut(out.toString().trim());
|
|
||||||
result.setExitStatus(exitStatus);
|
|
||||||
logger.debug("execute command: {}, out: {}, status: {}", command, out, exitStatus);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue