java执行linux命令和shell脚本

java程序中执行linux命令或者shell脚本依赖于Runtime和Process。

  • 每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime方法获取当前运行时环境。
  • ​ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法

执行命令代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private List<String> runCommand(String cmd, ResultProcessor processor) {
List<String> resultList = new ArrayList<String>();
String[] cmds = {"/bin/sh", "-c", cmd};
Process pro = null;
try {
pro = Runtime.getRuntime().exec(cmds);
pro.waitFor();
InputStream in = pro.getInputStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = read.readLine()) != null) {
processor.process(resultList, line);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

return resultList;
}
  • 参数cmd是需要执行linux命令或者shell脚本绝对位置;
  • 参数processor是对获得输出的处理器。

log方法

1
2
3
4
5
6
7
8
9
private void log(List<String> resultList){
if (resultList == null || resultList.size() == 0) {
System.out.println("resultList 为空");
return;
}
for (String result : resultList) {
System.out.println(result);
}
}

ResultProcessor

ResultProcessor是对命令输出分行依次处理。

1
2
3
public interface ResultProcessor {
void process(List<String> textList, String text);
}

简单命令pwd测试

1
2
3
4
5
6
7
8
 List<String> resultList = null;
resultList = runCommand("pwd", new ResultProcessor() {
@Override
public void process(List<String> textList, String text) {
textList.add(text);
}
});
log(resultList);

测试结果:
linux命令测试结果

shell脚本测试

分析Android项目依赖关系的shell脚本:

1
2
3
4
5
#!/usr/bin/env bash
cd $1
pwd
echo $1
./gradlew -q dependencies app:dependencies --configuration compile

这段shell脚本主要作用是分析当前目录$1下的module的依赖细节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
String projectDir = "/Users/zhaosc/bob/proj_ccare";
String gradleShellPath = "/Users/zhaosc/iFarSeer/ClassySharkTool/shell/gradle_dependencies.sh";
resultList = runCommand(gradleShellPath + " " + projectDir, new ResultProcessor() {
@Override
public void process(List<String> textList, String text) {
if (text.contains(":") && !text.contains("project :")
&& (text.indexOf(":") != text.lastIndexOf(":"))) {
text = text.substring(text.indexOf("- ") + 2);
if (!textList.contains(text)) {
textList.add(text);
}
}
}
});
log(resultList);

测试结果:
shell脚本测试结果