Java调用Shell脚本主要使用Runtime.exec()或ProcessBuilder。1. Runtime.getRuntime().exec()适合简单命令,如exec("/path/to/script.sh");需执行内置命令时应使用/bin/bash -c方式。2. ProcessBuilder更灵活,可设置工作目录、环境变量和重定向错误流,推荐用于复杂场景。3. 注意事项包括确保脚本有可执行权限、使用绝对路径、及时处理IO流防止阻塞,并调用waitFor()获取退出码。4. 执行带参数脚本可在命令后追加参数,如new ProcessBuilder("script.sh", "arg1", "arg2"),脚本通过$1、$2获取参数。

Java 调用 Shell 脚本的方法主要通过 Runtime.exec() 或 ProcessBuilder 来实现。这两种方式都可以启动外部进程执行 shell 命令或脚本,但在使用上略有差异。
1. 使用 Runtime.getRuntime().exec() 调用 Shell 脚本
这是最常见的方式,适合执行简单的命令或脚本。
示例代码:
public class ShellExecutor {
public static void main(String[] args) {
try {
// 执行一个 shell 脚本
Process process = Runtime.getRuntime().exec("/path/to/your/script.sh");
// 读取脚本输出
java.io.BufferedReader reader = new java.io.BufferedReader(
new java.io.InputStreamReader(process.getInputStream())
);
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待脚本执行完成
int exitCode = process.waitFor();
System.out.println("脚本退出码: " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:如果脚本需要执行 shell 内置命令(如 source、cd),应显式调用 bash/sh,并使用 -c 参数。
例如:
立即学习“Java免费学习笔记(深入)”;
Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", "source ~/.bashrc && your_command"});
2. 使用 ProcessBuilder 更灵活地控制环境
ProcessBuilder 提供了更丰富的配置选项,比如设置工作目录、环境变量、合并错误流等。
示例代码:
public class ProcessBuilderExample {
public static void main(String[] args) {
try {
ProcessBuilder pb = new ProcessBuilder(
"/bin/bash",
"/path/to/your/script.sh"
);
// 设置工作目录(可选)
pb.directory(new java.io.File("/your/work/dir"));
// 合并错误输出到标准输出(便于统一读取)
pb.redirectErrorStream(true);
Process process = pb.start();
// 读取输出
java.io.BufferedReader reader = new java.io.BufferedReader(
new java.io.InputStreamReader(process.getInputStream())
);
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("退出码: " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. 注意事项和常见问题
- 确保脚本有可执行权限:
chmod +x script.sh - 路径使用绝对路径,避免因工作目录不同导致找不到脚本
- 若脚本依赖特定环境变量,建议在脚本内部加载或通过 ProcessBuilder 设置
- 及时处理输入输出流,避免进程阻塞(尤其是输出较多时)
- 始终调用
waitFor()获取执行结果
4. 执行带参数的脚本
可以在命令数组中追加参数:
new ProcessBuilder("/bin/bash", "script.sh", "arg1", "arg2");
脚本中可通过 $1, $2 获取参数。










