我们项目里需要调用本地的 spark-submit 命令, 提交 spark 作业
这里举例如何使用 java 执行 shell 命令
/**
* 执行并返回状态码
*
* @param cmd
* @return
*/
public static int execRetCode(String cmd) {
boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
BufferedReader br = null;
try {
String prefix1 = isWindows ? "cmd" : "/bin/sh";
String prefix2 = isWindows ? "/c" : "-c";
// 这里务必是有命令前缀, 否则直接执行程序, 日志重定向是失败的. 例如 ping www.baidu.com > a.txt
Process p = Runtime.getRuntime().exec(new String[]{prefix1, prefix2, cmd});
// 0 表示正常
int returnCode = p.waitFor();
if (returnCode != 0) {
String charsetName = isWindows ? "GB2312" : "UTF-8";
// 这里务必是有命令前缀, 否则直接执行程序, 日志重定向是失败的. 例如 ping www.baidu.com > a.txt
br = new BufferedReader(new InputStreamReader(p.getErrorStream(), charsetName));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
log.error("shell 执行失败: {}", sb);
}
log.info("cmd = {}, returnCode = {}", cmd, returnCode);
return returnCode;
} catch (Exception e) {
e.printStackTrace();
return -1;
} finally {
if (br != null) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
需要注意的是, 如果在命令末尾传入 &
想要后台执行是不会生效的, java 调用方法仍然会被阻塞住, 我们可以使用线程池来执行上面的方法