
cloud.agileframework.common.util.shell.ShellUtil Maven / Gradle / Ivy
package cloud.agileframework.common.util.shell;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* @author 佟盟
* 日期 2020/5/7 9:39
* 描述 命令执行工具
* @version 1.0
* @since 1.0
*/
public class ShellUtil {
private ShellUtil() {
}
private static final Log log = LogFactory.getLog(ShellUtil.class);
private static final String ERROR_LOG = "执行命令时发生异常";
private static final ExecutorService POOL = new ThreadPoolExecutor(3, 3, 0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(), new ThreadPoolExecutor.CallerRunsPolicy());
/**
* @value 换行
*/
public static final String NEW_LINE = "\n";
/**
* 执行单条命令
*
* @param command 单条命令
* @return 执行结果
*/
public static Result execOut(String command) {
return execOut(null, null, command, 1, TimeUnit.MINUTES);
}
/**
* 执行单条命令
*
* @param commands 若干命令,最后合并为一条
* @return 执行结果
*/
public static Result execOut(String... commands) {
return execOut(null, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 执行单条命令
*
* @param env 环境变量
* @param commands 若干命令,最后合并为一条
* @return 执行结果
*/
public static Result execOut(String[] env, String... commands) {
return execOut(env, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 执行单条命令
*
* @param env 环境变量
* @param dir 之形目录
* @param command 单条命令
* @return 执行结果
*/
public static Result execOut(String[] env, File dir, String command, long timout, TimeUnit unit) {
Process process = null;
try {
process = Runtime.getRuntime().exec(command, env, dir);
return getResult(process, timout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ERROR_LOG, e);
return new Result(false, e.getMessage());
} catch (IOException | ExecutionException e) {
log.error(ERROR_LOG, e);
return new Result(false, e.getMessage());
} finally {
if (process != null) {
process.destroy();
}
}
}
/**
* 执行单条命令
*
* @param env 环境变量
* @param dir 之形目录
* @param commands 若干命令,最后合并为一条
* @return 执行结果
*/
public static Result execOut(String[] env, File dir, String[] commands, long timout, TimeUnit unit) {
Process process = null;
try {
process = Runtime.getRuntime().exec(commands, env, dir);
return getResult(process, timout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ERROR_LOG, e);
return new Result(false, e.getMessage());
} catch (IOException | ExecutionException e) {
log.error(ERROR_LOG, e);
return new Result(false, e.getMessage());
} finally {
if (process != null) {
process.destroy();
}
}
}
/**
* 执行多条命令
*
* @param commands 命令集合,每个元素将成为一条命令
* @return 执行结果
*/
public static Result batchExecOut(String... commands) {
return batchExecOut(null, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 执行多条命令
*
* @param env 环境变量
* @param commands 命令集合,每个元素将成为一条命令
* @return 执行结果
*/
public static Result batchExecOut(String[] env, String... commands) {
return batchExecOut(env, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 执行多条命令
*
* @param env 环境变量
* @param dir 执行目录
* @param commands 命令集合,每个元素将成为一条命令
* @return 执行结果
*/
public static Result batchExecOut(String[] env, File dir, String[] commands, long timeout, TimeUnit unit) {
Process process = null;
try {
process = Runtime.getRuntime().exec(commands[0], env, dir);
OutputStream outputStream = process.getOutputStream();
for (int i = 1; i < commands.length; i++) {
if (commands[i] == null) {
continue;
}
outputStream.write(commands[i].getBytes());
outputStream.write(NEW_LINE.getBytes());
}
// 不调用时终端无法判断是否完成写入,输入流读取时会造成堵塞
outputStream.flush();
outputStream.close();
return getResult(process, timeout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ERROR_LOG, e);
return new Result(false, e.getMessage());
} catch (IOException | ExecutionException e) {
log.error(ERROR_LOG, e);
return new Result(false, e.getMessage());
} finally {
if (process != null) {
process.destroy();
}
}
}
/**
* 获取Process中的正常或者异常流
*
* @param process Process对象
* @return 结果
* @throws InterruptedException 终端
*/
private static Result getResult(Process process, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException {
CompletableFuture successLog = CompletableFuture.supplyAsync(() -> {
try {
return IOUtils.toString(process.getInputStream(), Charset.defaultCharset());
} catch (IOException e) {
throw new RuntimeException(e);
}
}, POOL);
CompletableFuture errorLog = CompletableFuture.supplyAsync(() -> {
try {
return IOUtils.toString(process.getInputStream(), Charset.defaultCharset());
} catch (IOException e) {
throw new RuntimeException(e);
}
}, POOL);
CompletableFuture main = CompletableFuture.supplyAsync(() -> {
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
return process.exitValue() == 0;
});
boolean isSuccess = false;
try {
isSuccess = main.get(timeout, unit);
} catch (TimeoutException e) {
e.printStackTrace();
}
if (isSuccess) {
return new Result(true, successLog.get());
} else {
return new Result(true, errorLog.get());
}
}
/**
* 执行单条命令
*
* @param command 命令
* @return 结果
*/
public static boolean exec(String command) {
return exec(null, null, command, 1, TimeUnit.MINUTES);
}
/**
* 执行单条命令
*
* @param commands 最终合并为一条命令
* @return 结果
*/
public static boolean exec(String... commands) {
return exec(null, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 执行单条命令
*
* @param env 环境变量
* @param command 命令
* @return 结果
*/
public static boolean exec(String[] env, String command) {
return exec(env, null, command, 1, TimeUnit.MINUTES);
}
/**
* 执行单条命令
*
* @param env 环境变量
* @param dir 之形目录
* @param command 命令
* @return 结果
*/
public static boolean exec(String[] env, File dir, String command, long timeout, TimeUnit unit) {
try {
Process process = Runtime.getRuntime().exec(command, env, dir);
Future waitFuture = POOL.submit(() -> {
process.waitFor();
return process.exitValue() == 0;
});
return waitFuture.get(timeout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ERROR_LOG, e);
} catch (IOException | ExecutionException | TimeoutException e) {
log.error(ERROR_LOG, e);
}
return false;
}
/**
* 执行单条命令
*
* @param env 环境变量
* @param dir 之形目录
* @param commands 最终合并为一条命令
* @return 结果
*/
public static boolean exec(String[] env, File dir, String[] commands, long timeout, TimeUnit unit) {
try {
Process process = Runtime.getRuntime().exec(commands, env, dir);
Future waitFuture = POOL.submit(() -> {
process.waitFor();
return process.exitValue() == 0;
});
return waitFuture.get(timeout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ERROR_LOG, e);
} catch (IOException | ExecutionException | TimeoutException e) {
log.error(ERROR_LOG, e);
}
return false;
}
/**
* 批量执行命令
*
* @param commands 命令集合,每个元素视为一条命令
* @return 结果
*/
public static boolean batchExec(String... commands) {
return batchExec(null, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 批量执行命令
*
* @param env 环境变量
* @param commands 命令集合,每个元素视为一条命令
* @return 结果
*/
public static boolean batchExec(String[] env, String... commands) {
return batchExec(env, null, commands, 1, TimeUnit.MINUTES);
}
/**
* 批量执行命令
*
* @param env 环境变量
* @param dir 执行目录
* @param commands 命令集合,每个元素视为一条命令
* @return 结果
*/
public static boolean batchExec(String[] env, File dir, String[] commands, long timeout, TimeUnit unit) {
try {
Process process = Runtime.getRuntime().exec(commands[0], env, dir);
OutputStream outputStream = process.getOutputStream();
for (int i = 1; i < commands.length; i++) {
if (commands[i] == null) {
continue;
}
outputStream.write(commands[i].getBytes());
outputStream.write(NEW_LINE.getBytes());
}
outputStream.flush();
outputStream.close();
Future waitFuture = POOL.submit(() -> {
process.waitFor();
return process.exitValue() == 0;
});
return waitFuture.get(timeout, unit);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error(ERROR_LOG, e);
} catch (IOException | ExecutionException | TimeoutException e) {
log.error(ERROR_LOG, e);
}
return false;
}
/**
* 结果
*/
public static class Result {
private final boolean success;
private final String log;
public Result(boolean success, String log) {
this.success = success;
this.log = log;
}
public boolean success() {
return success;
}
public String log() {
return log;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy