|
@@ -0,0 +1,513 @@
|
|
|
|
|
+package cn.exlive.monitor.utils;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+import cn.exlive.monitor.config.ProgramsConfig;
|
|
|
|
|
+import org.apache.commons.exec.CommandLine;
|
|
|
|
|
+import org.apache.commons.exec.DefaultExecuteResultHandler;
|
|
|
|
|
+import org.apache.commons.exec.DefaultExecutor;
|
|
|
|
|
+import org.apache.commons.exec.ExecuteResultHandler;
|
|
|
|
|
+import org.apache.commons.exec.ExecuteWatchdog;
|
|
|
|
|
+import org.apache.commons.exec.ProcessDestroyer;
|
|
|
|
|
+import org.apache.commons.exec.PumpStreamHandler;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
+import org.apache.commons.lang3.SystemUtils;
|
|
|
|
|
+import org.apache.commons.lang3.exception.ExceptionUtils;
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.boot.system.ApplicationHome;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.BufferedInputStream;
|
|
|
|
|
+import java.io.BufferedReader;
|
|
|
|
|
+import java.io.File;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.io.InputStreamReader;
|
|
|
|
|
+import java.io.Reader;
|
|
|
|
|
+import java.time.Duration;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Objects;
|
|
|
|
|
+import java.util.Optional;
|
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 便捷得 Shell 执行工具类
|
|
|
|
|
+ *
|
|
|
|
|
+ * <pre>
|
|
|
|
|
+ *
|
|
|
|
|
+ * Created by zhaopx.
|
|
|
|
|
+ * Date: 2025/6/9
|
|
|
|
|
+ * Time: 12:00
|
|
|
|
|
+ * Vendor: exlive.cn
|
|
|
|
|
+ *
|
|
|
|
|
+ * </pre>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author zhaopx
|
|
|
|
|
+ */
|
|
|
|
|
+public class ShellUtils {
|
|
|
|
|
+
|
|
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(ShellUtils.class);
|
|
|
|
|
+
|
|
|
|
|
+ public static String INSTALL_PATH = getInstallPath();
|
|
|
|
|
+
|
|
|
|
|
+ public final static String OS = SystemUtils.IS_OS_LINUX ? "linux" : "windows";
|
|
|
|
|
+
|
|
|
|
|
+ private static ProcessBuilder processBuilder = new ProcessBuilder();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 返回 App HOME
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ private static String getInstallPath() {
|
|
|
|
|
+ String appHome = System.getenv("APP_HOME");
|
|
|
|
|
+ if(StringUtils.isBlank(appHome)) {
|
|
|
|
|
+ appHome = System.getProperty("app.home");
|
|
|
|
|
+ }
|
|
|
|
|
+ if(StringUtils.isBlank(appHome)) {
|
|
|
|
|
+ // appHome = "D:/Work/Deploy";
|
|
|
|
|
+ ApplicationHome ah = new ApplicationHome(ShellUtils.class);
|
|
|
|
|
+ // 获取jar包所在目录
|
|
|
|
|
+ File source = ah.getSource();
|
|
|
|
|
+ File dir = ah.getDir();
|
|
|
|
|
+ if(source == null && dir == null) {
|
|
|
|
|
+ throw new IllegalStateException("请设置 Monitor APP_HOME 环境变量。");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(source == null && dir != null) {
|
|
|
|
|
+ appHome = dir.getParentFile().getAbsolutePath();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ File appHomeFile = Optional.ofNullable(source.getParentFile()).map(File::getParentFile).orElseGet(()->{
|
|
|
|
|
+ String userDir = System.getProperty("user.dir");
|
|
|
|
|
+ return new File(org.springframework.util.StringUtils.hasLength(userDir) ? userDir : ".");
|
|
|
|
|
+ });
|
|
|
|
|
+ appHome = appHomeFile.getAbsolutePath();
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.warn("use app home: {} recommen user set APP_HOME envirment.", appHome);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // monitor app home 的上一层是 INSTALL_DIR
|
|
|
|
|
+ File homeDir = new File(appHome);
|
|
|
|
|
+ String installPath = homeDir.getParentFile().getAbsolutePath();
|
|
|
|
|
+ logger.info("INSTALL_PATH: {}", installPath);
|
|
|
|
|
+ File dataDir = new File(homeDir, "data");
|
|
|
|
|
+ if(!dataDir.exists()) {
|
|
|
|
|
+ dataDir.mkdir();
|
|
|
|
|
+ logger.info("mkdir monitor data dir: {}", dataDir.getAbsolutePath());
|
|
|
|
|
+ }
|
|
|
|
|
+ return installPath;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param pathOrCommand 脚本路径或者命令
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static ExecResult exceShell(String pathOrCommand) {
|
|
|
|
|
+ ExecResult result = new ExecResult();
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 执行脚本
|
|
|
|
|
+ Process ps = Runtime.getRuntime().exec(new String[]{"sh", "-c", pathOrCommand});
|
|
|
|
|
+ // 只能接收脚本echo打印的数据,并且是echo打印的最后一次数据
|
|
|
|
|
+ BufferedInputStream in = new BufferedInputStream(ps.getInputStream());
|
|
|
|
|
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
|
|
|
|
+ String line;
|
|
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
|
|
+ stringBuffer.append(line);
|
|
|
|
|
+ stringBuffer.append(System.lineSeparator());
|
|
|
|
|
+ }
|
|
|
|
|
+ in.close();
|
|
|
|
|
+ br.close();
|
|
|
|
|
+ String execOut = stringBuffer.toString();
|
|
|
|
|
+ int exitValue = ps.waitFor();
|
|
|
|
|
+ result.setReturnCode(exitValue);
|
|
|
|
|
+ if (0 == exitValue) {
|
|
|
|
|
+ logger.info("{} command exec out is : {} {}", pathOrCommand, System.lineSeparator(), execOut);
|
|
|
|
|
+ result.setExecResult(true);
|
|
|
|
|
+ result.setExecOut(execOut);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ result.setExecOut("call shell failed. error code is :" + exitValue);
|
|
|
|
|
+ logger.error("{} command exec out is : {} {}", pathOrCommand, System.lineSeparator(), execOut);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ result.setExecOut(e.getMessage());
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取cpu架构 arm或x86
|
|
|
|
|
+ public static String getCpuArchitecture() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ Process ps = Runtime.getRuntime().exec("arch");
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ int exitValue = ps.waitFor();
|
|
|
|
|
+ if (0 == exitValue) {
|
|
|
|
|
+ // 只能接收脚本echo打印的数据,并且是echo打印的最后一次数据
|
|
|
|
|
+ BufferedInputStream in = new BufferedInputStream(ps.getInputStream());
|
|
|
|
|
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
|
|
|
|
+ String line;
|
|
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
|
|
+ logger.info("脚本返回的数据如下: " + line);
|
|
|
|
|
+ stringBuffer.append(line);
|
|
|
|
|
+ }
|
|
|
|
|
+ in.close();
|
|
|
|
|
+ br.close();
|
|
|
|
|
+ return stringBuffer.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult execWithStatus(String workPath, List<String> command, long timeout) {
|
|
|
|
|
+ Process process = null;
|
|
|
|
|
+ ExecResult result = new ExecResult();
|
|
|
|
|
+ try {
|
|
|
|
|
+ processBuilder.directory(new File(workPath));
|
|
|
|
|
+ processBuilder.environment();
|
|
|
|
|
+ processBuilder.command(command);
|
|
|
|
|
+ processBuilder.redirectErrorStream(true);
|
|
|
|
|
+ process = processBuilder.start();
|
|
|
|
|
+ printOutput(process);
|
|
|
|
|
+ boolean execResult = process.waitFor(timeout, TimeUnit.SECONDS);
|
|
|
|
|
+ result.setReturnCode(process.exitValue());
|
|
|
|
|
+ if (execResult && process.exitValue() == 0) {
|
|
|
|
|
+ logger.info("script execute success");
|
|
|
|
|
+ result.setExecResult(true);
|
|
|
|
|
+ result.setExecOut("script execute success");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ result.setExecOut("script execute failed");
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ result.setExecErrOut(e.getMessage());
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult execWithLogs(String workPath, List<String> command, long timeout) {
|
|
|
|
|
+ Process process = null;
|
|
|
|
|
+ ExecResult result = new ExecResult();
|
|
|
|
|
+ try {
|
|
|
|
|
+ processBuilder.directory(new File(workPath));
|
|
|
|
|
+ processBuilder.environment();
|
|
|
|
|
+ processBuilder.command(command);
|
|
|
|
|
+ processBuilder.redirectErrorStream(true);
|
|
|
|
|
+ process = processBuilder.start();
|
|
|
|
|
+ String output = getOutput(process);
|
|
|
|
|
+ boolean execResult = process.waitFor(timeout, TimeUnit.SECONDS);
|
|
|
|
|
+ result.setReturnCode(process.exitValue());
|
|
|
|
|
+ result.setExecOut(output);
|
|
|
|
|
+ if (execResult && process.exitValue() == 0) {
|
|
|
|
|
+ logger.info("script execute success");
|
|
|
|
|
+ result.setExecResult(true);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ result.setExecErrOut(e.getMessage());
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult execWithStatus(String workPath, List<String> command, long timeout, Logger logger) {
|
|
|
|
|
+ Process process = null;
|
|
|
|
|
+ ExecResult result = new ExecResult();
|
|
|
|
|
+ try {
|
|
|
|
|
+ processBuilder.directory(new File(workPath));
|
|
|
|
|
+ processBuilder.environment();
|
|
|
|
|
+ processBuilder.command(command);
|
|
|
|
|
+ processBuilder.redirectErrorStream(true);
|
|
|
|
|
+ process = processBuilder.start();
|
|
|
|
|
+ getOutput(process, logger);
|
|
|
|
|
+ boolean execResult = process.waitFor(timeout, TimeUnit.SECONDS);
|
|
|
|
|
+ result.setReturnCode(process.exitValue());
|
|
|
|
|
+ if (execResult && process.exitValue() == 0) {
|
|
|
|
|
+ logger.info("script execute success");
|
|
|
|
|
+ result.setExecResult(true);
|
|
|
|
|
+ result.setExecOut("script execute success");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ result.setExecOut("script execute failed");
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ result.setExecErrOut(e.getMessage());
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void getOutput(Process process, Logger logger) {
|
|
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
|
|
+ BufferedReader inReader = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ inReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
|
|
+ String line;
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ while ((line = inReader.readLine()) != null) {
|
|
|
|
|
+ stringBuffer.append(line);
|
|
|
|
|
+ stringBuffer.append(System.lineSeparator());
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.info(stringBuffer.toString());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error(e.getMessage(), e);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ closeQuietly(inReader);
|
|
|
|
|
+ }
|
|
|
|
|
+ BufferedReader errorReader = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
|
|
|
|
+ String line;
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ while ((line = errorReader.readLine()) != null) {
|
|
|
|
|
+ stringBuffer.append(line);
|
|
|
|
|
+ stringBuffer.append(System.lineSeparator());
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.error(stringBuffer.toString());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error(e.getMessage(), e);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ closeQuietly(errorReader);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static String getOutput(Process process) {
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ BufferedReader inReader = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ inReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
|
|
+ String line;
|
|
|
|
|
+ while ((line = inReader.readLine()) != null) {
|
|
|
|
|
+ stringBuffer.append(line);
|
|
|
|
|
+ stringBuffer.append(System.lineSeparator());
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error(e.getMessage(), e);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ closeQuietly(inReader);
|
|
|
|
|
+ }
|
|
|
|
|
+ return stringBuffer.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static void printOutput(Process process) {
|
|
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
|
|
+ BufferedReader inReader = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ inReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
|
|
+ String line;
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ while ((line = inReader.readLine()) != null) {
|
|
|
|
|
+ stringBuffer.append(line);
|
|
|
|
|
+ stringBuffer.append(System.lineSeparator());
|
|
|
|
|
+ }
|
|
|
|
|
+ logger.trace(stringBuffer.toString());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ logger.error(e.getMessage(), e);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ closeQuietly(inReader);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static String getError(Process process) {
|
|
|
|
|
+ String errput = null;
|
|
|
|
|
+ BufferedReader reader = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (process != null) {
|
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
|
+ reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
|
|
|
|
+ while (reader.read() != -1) {
|
|
|
|
|
+ stringBuffer.append("\n" + reader.readLine());
|
|
|
|
|
+ }
|
|
|
|
|
+ errput = stringBuffer.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ closeQuietly(reader);
|
|
|
|
|
+ return errput;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String commands) {
|
|
|
|
|
+ return exec(null, CommandLine.parse(commands), new HashMap<>(), -1, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String commands, int timeoutSecond) {
|
|
|
|
|
+ return exec(null, CommandLine.parse(commands), new HashMap<>(), timeoutSecond, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String workPath, String commands) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse(commands), new HashMap<>(), -1, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String workPath, String commands, int timeoutSecond) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse( commands), new HashMap<>(), timeoutSecond, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 执行命令,并返回回调信息
|
|
|
|
|
+ * @param workPath
|
|
|
|
|
+ * @param commands
|
|
|
|
|
+ * @param timeoutSecond
|
|
|
|
|
+ * @param executeResultHandler
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static ExecResult exec(String workPath, String commands, int timeoutSecond, BrodcastExecuteResultHandler executeResultHandler) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse( commands), new HashMap<>(), timeoutSecond, executeResultHandler);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String workPath, String commands, Map<String, String> envs, int timeoutSecond) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse( commands), envs, timeoutSecond, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 执行命令,并返回回调信息
|
|
|
|
|
+ * @param workPath
|
|
|
|
|
+ * @param commands
|
|
|
|
|
+ * @param timeoutSecond
|
|
|
|
|
+ * @param executeResultHandler
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static ExecResult exec(String workPath, String commands, Map<String, String> envs, int timeoutSecond, BrodcastExecuteResultHandler executeResultHandler) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse( commands), envs, timeoutSecond, executeResultHandler);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(List<String> commands) {
|
|
|
|
|
+ return exec(null, CommandLine.parse(StringUtils.join(commands, " ")), new HashMap<>(), -1, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(List<String> commands, int timeoutSecond) {
|
|
|
|
|
+ return exec(null, CommandLine.parse(StringUtils.join(commands, " ")), new HashMap<>(), timeoutSecond, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String workPath, List<String> commands) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse(StringUtils.join(commands, " ")), new HashMap<>(), -1, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String workPath, List<String> commands, int timeoutSecond) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse(StringUtils.join(commands, " ")), new HashMap<>(), timeoutSecond, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 带有回调的执行命令
|
|
|
|
|
+ * @param workPath
|
|
|
|
|
+ * @param commands
|
|
|
|
|
+ * @param timeoutSecond
|
|
|
|
|
+ * @param executeResultHandler
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static ExecResult exec(String workPath, List<String> commands, int timeoutSecond, BrodcastExecuteResultHandler executeResultHandler) {
|
|
|
|
|
+ return exec(workPath, CommandLine.parse(StringUtils.join(commands, " ")), new HashMap<>(), timeoutSecond, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ExecResult exec(String workPath, CommandLine commandLine, Map<String, String> envs, int timeoutSecond, DefaultExecuteResultHandler handler) {
|
|
|
|
|
+ DefaultExecutor executor = new DefaultExecutor();
|
|
|
|
|
+ executor.setExitValue(-1);
|
|
|
|
|
+ // handler 记录
|
|
|
|
|
+ handler = (handler == null ? new DefaultExecuteResultHandler() : handler);
|
|
|
|
|
+ ShellLogOutputStream output = new ShellLogOutputStream();
|
|
|
|
|
+ ShellLogOutputStream err = new ShellLogOutputStream();
|
|
|
|
|
+ executor.setStreamHandler(new PumpStreamHandler(output, err));
|
|
|
|
|
+ PidExecuteWatchdog watchDog = null;
|
|
|
|
|
+ // 不限时间
|
|
|
|
|
+ if(timeoutSecond > 0) {
|
|
|
|
|
+ watchDog = new PidExecuteWatchdog(Duration.ofSeconds(timeoutSecond).toMillis(), handler);
|
|
|
|
|
+ executor.setWatchdog(watchDog);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String exeScript = "bash";
|
|
|
|
|
+ if (SystemUtils.IS_OS_WINDOWS) {
|
|
|
|
|
+ // windows 系统不需要执行,也没有权限
|
|
|
|
|
+ exeScript = "";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Linux, Mac 系统使用 bash 直接执行脚本
|
|
|
|
|
+ exeScript = "bash";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // String cmd = StringUtils.join(commands, " ");
|
|
|
|
|
+ if(StringUtils.isNotBlank(workPath)) {
|
|
|
|
|
+ logger.info("from path: {} execute cmd: {}", workPath, commandLine);
|
|
|
|
|
+ executor.setWorkingDirectory(new File(workPath));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ logger.info("execute cmd: " + commandLine);
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, String> environment = new HashMap<>(System.getenv());
|
|
|
|
|
+ if(envs != null && !envs.isEmpty()) {
|
|
|
|
|
+ environment.putAll(envs);
|
|
|
|
|
+ }
|
|
|
|
|
+ ExecResult result = new ExecResult();
|
|
|
|
|
+ final long start = System.currentTimeMillis();
|
|
|
|
|
+ try {
|
|
|
|
|
+ executor.execute(commandLine, environment, handler);
|
|
|
|
|
+ try {
|
|
|
|
|
+ result.setPid(watchDog != null ? watchDog.getProcessPid() : -1);
|
|
|
|
|
+ } catch (Exception ignore) {}
|
|
|
|
|
+ if (timeoutSecond > 0) {
|
|
|
|
|
+ handler.waitFor(Duration.ofSeconds(timeoutSecond));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ handler.waitFor();
|
|
|
|
|
+ }
|
|
|
|
|
+ int exitCode = handler.getExitValue();
|
|
|
|
|
+ result.setUseTime(System.currentTimeMillis() - start);
|
|
|
|
|
+ result.setExecOut(output.toString());
|
|
|
|
|
+ result.setReturnCode(exitCode);
|
|
|
|
|
+ result.setExecErrOut(err.toString());
|
|
|
|
|
+ result.setExecResult(Objects.equals(0, exitCode));
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ result.setUseTime(System.currentTimeMillis() - start);
|
|
|
|
|
+ result.setExecResult(false);
|
|
|
|
|
+ result.setReturnCode(-1);
|
|
|
|
|
+ result.setExecOut(output.toString());
|
|
|
|
|
+ result.setExecErrOut(ExceptionUtils.getRootCauseMessage(e));
|
|
|
|
|
+ logger.error("execute: " + commandLine + " error.", e);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void closeQuietly(Reader reader) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (reader != null) {
|
|
|
|
|
+ reader.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (IOException ioe) {
|
|
|
|
|
+ ioe.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void destroy(Process process) {
|
|
|
|
|
+ if (process != null) {
|
|
|
|
|
+ process.destroyForcibly();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void addChmod(String path, String chmod) {
|
|
|
|
|
+ ArrayList<String> command = new ArrayList<>();
|
|
|
|
|
+ command.add("chmod");
|
|
|
|
|
+ command.add("-R");
|
|
|
|
|
+ command.add(chmod);
|
|
|
|
|
+ command.add(path);
|
|
|
|
|
+ execWithStatus(INSTALL_PATH, command, 60, logger);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static void addChown(String path, String user, String group) {
|
|
|
|
|
+ ArrayList<String> command = new ArrayList<>();
|
|
|
|
|
+ command.add("chown");
|
|
|
|
|
+ command.add("-R");
|
|
|
|
|
+ command.add(user + ":" + group);
|
|
|
|
|
+ command.add(path);
|
|
|
|
|
+ execWithStatus(INSTALL_PATH, command, 60, logger);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|