|
@@ -9,137 +9,88 @@ import java.io.InputStreamReader;
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
|
+import java.util.UUID;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @author reghao
|
|
* @author reghao
|
|
|
* @date 2019-08-20 23:45:06
|
|
* @date 2019-08-20 23:45:06
|
|
|
*/
|
|
*/
|
|
|
public class ShellExecutor {
|
|
public class ShellExecutor {
|
|
|
- @Deprecated
|
|
|
|
|
- private InputStreamReader outstream;
|
|
|
|
|
- @Deprecated
|
|
|
|
|
- private InputStreamReader errstream;
|
|
|
|
|
|
|
+ private final String PATH;
|
|
|
|
|
+ private final String SHELL;
|
|
|
|
|
+ private TextFile textFile;
|
|
|
|
|
+
|
|
|
|
|
+ public ShellExecutor() {
|
|
|
|
|
+ this.PATH = System.getenv("PATH");
|
|
|
|
|
+ this.SHELL = System.getenv("SHELL");
|
|
|
|
|
+ this.textFile = new TextFile();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @param scriptPath shell 脚本绝对路径
|
|
|
|
|
- * @param args 日志文件以 .log 为后缀,且必须为数组的第一个元素(若存在日志文件)
|
|
|
|
|
|
|
+ * 执行 shell 命令
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param dir 执行命令所处的目录
|
|
|
|
|
+ * @param cmd shell 命令
|
|
|
|
|
+ * @param longLog shell 命令是否会输出长日志(长日志会重定向到一个临时文件)
|
|
|
* @return
|
|
* @return
|
|
|
- * @date 2020-11-09 下午7:22
|
|
|
|
|
|
|
+ * @date 2020-11-09 下午11:22
|
|
|
*/
|
|
*/
|
|
|
- public ShellResult execute(String scriptPath, String... args) throws Exception {
|
|
|
|
|
- List<String> commands = new ArrayList<>();
|
|
|
|
|
- commands.add("sh");
|
|
|
|
|
- commands.add(scriptPath);
|
|
|
|
|
- commands.addAll(Arrays.asList(args));
|
|
|
|
|
- ProcessBuilder pb = new ProcessBuilder(commands);
|
|
|
|
|
- ShellResult shellResult = exec(pb);
|
|
|
|
|
- if (args.length != 0 && args[0].endsWith(".log")) {
|
|
|
|
|
- // 读取日志文件的内容
|
|
|
|
|
- TextFile textFile = new TextFile();
|
|
|
|
|
- if (shellResult.hasError()) {
|
|
|
|
|
- shellResult.setStderr(textFile.readFile(args[0]));
|
|
|
|
|
- } else {
|
|
|
|
|
- shellResult.setStdout(textFile.readFile(args[0]));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return shellResult;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Deprecated
|
|
|
|
|
- public ShellResult execute(String script) {
|
|
|
|
|
- String dir = System.getProperty("user.home");
|
|
|
|
|
- return execute0(dir, script);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Deprecated
|
|
|
|
|
- public ShellResult execute(String dir, String script) {
|
|
|
|
|
|
|
+ public ShellResult execCommand(String dir, String cmd, boolean longLog) throws Exception {
|
|
|
if (dir == null) {
|
|
if (dir == null) {
|
|
|
- return null;
|
|
|
|
|
|
|
+ dir = System.getProperty("user.home");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return execute0(dir, script);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // TODO: 输出流有大量数据时程序会阻塞
|
|
|
|
|
- @Deprecated
|
|
|
|
|
- private ShellResult execute0(String dir, String script) {
|
|
|
|
|
- String cmd = "cd " + dir + " && ";
|
|
|
|
|
- cmd += script;
|
|
|
|
|
- ShellResult result = new ShellResult();
|
|
|
|
|
- ProcessBuilder pb = new ProcessBuilder("sh", "-c", cmd);
|
|
|
|
|
- try {
|
|
|
|
|
- Process process = pb.start();
|
|
|
|
|
- errstream = new InputStreamReader(process.getErrorStream());
|
|
|
|
|
- outstream = new InputStreamReader(process.getInputStream());
|
|
|
|
|
-
|
|
|
|
|
- ShellOutput stderr = new ShellOutput(new BufferedReader(errstream));
|
|
|
|
|
- ShellOutput stdout = new ShellOutput(new BufferedReader(outstream));
|
|
|
|
|
- stderr.start();
|
|
|
|
|
- stdout.start();
|
|
|
|
|
-
|
|
|
|
|
- while (!stderr.isFinished() && !stdout.isFinished()) {
|
|
|
|
|
- Thread.sleep(1_000);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
|
|
+ list.add("cd " + dir);
|
|
|
|
|
+ String logfile = "";
|
|
|
|
|
+ if (longLog) {
|
|
|
|
|
+ logfile = System.getProperty("java.io.tmpdir") + "/" + UUID.randomUUID().toString() + ".log";
|
|
|
|
|
+ list.add(cmd + " > " + logfile + " 2>&1");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ list.add(cmd);
|
|
|
|
|
+ }
|
|
|
|
|
+ String scriptPath = System.getProperty("java.io.tmpdir") + "/" + UUID.randomUUID().toString() + ".sh";
|
|
|
|
|
+ textFile.write(scriptPath, list);
|
|
|
|
|
|
|
|
- result.setStdout(stdout.output());
|
|
|
|
|
- result.setStderr(stderr.output());
|
|
|
|
|
- result.setExitCode(process.waitFor());
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
- } finally {
|
|
|
|
|
- try {
|
|
|
|
|
- if (errstream != null) {
|
|
|
|
|
- errstream.close();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (outstream != null) {
|
|
|
|
|
- outstream.close();
|
|
|
|
|
- }
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
|
|
+ ProcessBuilder pb = new ProcessBuilder("sh", scriptPath);
|
|
|
|
|
+ ShellResult shellResult = exec(pb);
|
|
|
|
|
+ if (longLog) {
|
|
|
|
|
+ if (shellResult.hasError()) {
|
|
|
|
|
+ shellResult.setStderr(textFile.readFile(logfile));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ shellResult.setStdout(textFile.readFile(logfile));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // TODO: null 异常
|
|
|
|
|
- return result;
|
|
|
|
|
|
|
+ return shellResult;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @Deprecated
|
|
|
|
|
- static class ShellOutput extends Thread {
|
|
|
|
|
- private BufferedReader in;
|
|
|
|
|
- private StringBuilder output = new StringBuilder();
|
|
|
|
|
- private boolean isFinished = false;
|
|
|
|
|
-
|
|
|
|
|
- private ShellOutput(BufferedReader in) {
|
|
|
|
|
- this.in = in;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private String output() {
|
|
|
|
|
- return output.toString();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private boolean isFinished() {
|
|
|
|
|
- return this.isFinished;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 执行 shell 脚本
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param scriptPath shell 脚本绝对路径
|
|
|
|
|
+ * @param args 日志文件以 .log 为后缀,且必须为数组的第一个元素(若存在日志文件)
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @date 2020-11-09 下午7:22
|
|
|
|
|
+ */
|
|
|
|
|
+ public ShellResult execScript(String scriptPath, String... args) throws Exception {
|
|
|
|
|
+ String logfile = System.getProperty("java.io.tmpdir") + "/" + UUID.randomUUID().toString() + ".log";
|
|
|
|
|
+ List<String> commands = new ArrayList<>();
|
|
|
|
|
+ commands.add("sh");
|
|
|
|
|
+ commands.add(scriptPath);
|
|
|
|
|
+ commands.add(logfile);
|
|
|
|
|
+ commands.addAll(Arrays.asList(args));
|
|
|
|
|
|
|
|
- @Override
|
|
|
|
|
- public void run() {
|
|
|
|
|
- readStream(in);
|
|
|
|
|
|
|
+ ProcessBuilder pb = new ProcessBuilder(commands);
|
|
|
|
|
+ ShellResult shellResult = exec(pb);
|
|
|
|
|
+ // 读取日志文件的内容
|
|
|
|
|
+ if (shellResult.hasError()) {
|
|
|
|
|
+ shellResult.setStderr(textFile.readFile(logfile));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ shellResult.setStdout(textFile.readFile(logfile));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void readStream(BufferedReader reader) {
|
|
|
|
|
- String line;
|
|
|
|
|
- try {
|
|
|
|
|
- while ((line = reader.readLine()) != null) {
|
|
|
|
|
- output.append(line).append(System.lineSeparator());
|
|
|
|
|
- }
|
|
|
|
|
- reader.close();
|
|
|
|
|
- isFinished = true;
|
|
|
|
|
- } catch (IOException e) {
|
|
|
|
|
- e.printStackTrace();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return shellResult;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private ShellResult exec(ProcessBuilder pb) throws Exception {
|
|
private ShellResult exec(ProcessBuilder pb) throws Exception {
|
|
@@ -169,15 +120,22 @@ public class ShellExecutor {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
public static void main(String[] args) throws Exception {
|
|
|
- String script = "/home/reghao/scripts/cron/cron_rsync.sh";
|
|
|
|
|
- script = "/home/reghao/work/azy/svn/test/4-运维管理/构建部署/自动化脚本/build_app.sh";
|
|
|
|
|
- String[] arr = new String[2];
|
|
|
|
|
- //arr[0] = "/tmp/content1.log";
|
|
|
|
|
- arr[0] = "content";
|
|
|
|
|
- arr[1] = "/home/reghao/opt/data/autodop/compile-dir/content/ContentService/4-ContentPresentation/Com.IQuizoo.ContentService";
|
|
|
|
|
-
|
|
|
|
|
- ShellExecutor shellExecutor = new ShellExecutor();
|
|
|
|
|
- ShellResult shellResult = shellExecutor.execute(script, arr);
|
|
|
|
|
- System.out.println();
|
|
|
|
|
|
|
+ String cmd = "rsync -avzP --delete --password-file=/home/reghao/scripts/cron/rsyncd_secret azy@192.168.0.50::nexus /home/reghao/opt/data/backup/nexus/";
|
|
|
|
|
+ String script = "/home/reghao/work/azy/svn/test/4-运维管理/备份还原/rsync.sh";
|
|
|
|
|
+
|
|
|
|
|
+ ShellExecutor executor = new ShellExecutor();
|
|
|
|
|
+ /*ShellResult result = executor.execCommand(null, cmd, false);
|
|
|
|
|
+ if (result.hasError()) {
|
|
|
|
|
+ System.out.println(result.getStderr());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ System.out.println(result.getStdout());
|
|
|
|
|
+ }*/
|
|
|
|
|
+
|
|
|
|
|
+ ShellResult shellResult = executor.execScript(script);
|
|
|
|
|
+ if (shellResult.hasError()) {
|
|
|
|
|
+ System.out.println(shellResult.getStderr());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ System.out.println(shellResult.getStdout());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|