说明

执行linux命令可以用Runtime来执行,但是不是很方便,而且需要做很多额外的操作,如windows的换行符等,
这里采用 apache的 commons-exec 包来处理

引入依赖

maven 依赖

1
2
3
4
5
6
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>

应用中使用

应用中直接组装好shell语句,然后执行方法即可,方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 执行指定命令,输出结果到指定输出流中
*
* @param command 命令
* @param out 执行结果输出流
* @return 执行结果状态码:执行成功返回0
* @throws ExecuteException 失败时抛出异常,由调用者捕获处理
* @throws IOException 失败时抛出异常,由调用者捕获处理
*/
public synchronized static int exeCommand(String command, OutputStream out) throws ExecuteException, IOException {

log.info("执行的命令: {}",command)
//构造命令
CommandLine commandLine = CommandLine.parse(command);

//获取到PumpStreamHandler,默认用这就好了
PumpStreamHandler pumpStreamHandler = null;
if (null == out) {
pumpStreamHandler = new PumpStreamHandler();
} else {
pumpStreamHandler = new PumpStreamHandler(out);
}
// 设置超时时间为10秒 , -1为不设置超时时间
//ExecuteWatchdog watchdog = new ExecuteWatchdog(TIMEOUT);
ExecuteWatchdog watchdog = new ExecuteWatchdog(-1);

//执行器
DefaultExecutor executor = new DefaultExecutor();
executor.setStreamHandler(pumpStreamHandler);
executor.setWatchdog(watchdog);
//执行
return executor.execute(commandLine);
}

总的来说就执行就好了,这里的OutputStream可要可不要,可以封装一个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public synchronized static String exeCommand(String command) throws RuntimeException {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
//调用上面的方法
int exitCode = exeCommand(command, out);
if (exitCode == 0) {
logger.info("命令运行成功:" + System.currentTimeMillis());
} else {
logger.error("命令运行失败:" + System.currentTimeMillis());
}
//输出流,一般不用
return out.toString(DEFAULT_CHARSET);
} catch (Exception e) {
logger.info(ExceptionUtils.getStackTrace(e));
throw new RuntimeException(ExceptionUtils.getStackTrace(e));
}
}

注意执行命令时可能报错 commons-exec Process exited with an error: 11 或者 9 1 等数字,注意检查下命令是否正确

封装的工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

public class CommandUtil {

private static Logger logger = LoggerFactory.getLogger(CommandUtil.class.getSimpleName());
private static final String DEFAULT_CHARSET = "UTF-8";
private static final Long TIMEOUT = 10000L;

/**
* 执行指定命令
*
* @param command 命令
* @return 命令执行完成返回结果
* @throws RuntimeException 失败时抛出异常,由调用者捕获处理
*/
public synchronized static String exeCommand(String command) throws RuntimeException {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
int exitCode = exeCommand(command, out);
if (exitCode == 0) {
logger.info("命令运行成功:" + System.currentTimeMillis());
} else {
logger.error("命令运行失败:" + System.currentTimeMillis());
}
return out.toString(DEFAULT_CHARSET);
} catch (Exception e) {
logger.info(ExceptionUtils.getStackTrace(e));
throw new RuntimeException(ExceptionUtils.getStackTrace(e));
}
}

/**
* 执行指定命令,输出结果到指定输出流中
*
* @param command 命令
* @param out 执行结果输出流
* @return 执行结果状态码:执行成功返回0
* @throws ExecuteException 失败时抛出异常,由调用者捕获处理
* @throws IOException 失败时抛出异常,由调用者捕获处理
*/
public synchronized static int exeCommand(String command, OutputStream out) throws ExecuteException, IOException {
CommandLine commandLine = CommandLine.parse(command);
PumpStreamHandler pumpStreamHandler = null;
if (null == out) {
pumpStreamHandler = new PumpStreamHandler();
} else {
pumpStreamHandler = new PumpStreamHandler(out);
}
// 设置超时时间为10秒
//ExecuteWatchdog watchdog = new ExecuteWatchdog(TIMEOUT);
ExecuteWatchdog watchdog = new ExecuteWatchdog(-1);
DefaultExecutor executor = new DefaultExecutor();
executor.setStreamHandler(pumpStreamHandler);
executor.setWatchdog(watchdog);
return executor.execute(commandLine);
}

public static void main(String[] args) {
logger.info(exeCommand("pwd"));
logger.info(exeCommand("ls"));
}

}

引用忘了具体的文章了,没找到链接