Java如何调用cmd命令行?
- 电脑教程
- 2025-06-13
- 6
核心方法:Runtime.exec()
Runtime.getRuntime().exec() 是Java早期提供的API,适用于简单命令调用。
基础示例
try { // 执行dir命令(Windows)或ls命令(Linux/Mac) Process process = Runtime.getRuntime().exec("cmd /c dir C:\"); // 获取命令输出流 BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()) ); // 读取输出内容 String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待命令执行完成(阻塞当前线程) int exitCode = process.waitFor(); System.out.println("Exit Code: " + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); }
关键参数说明
- cmd /c [命令]:Windows中/c表示执行后关闭cmd窗口。
- 若命令含空格(如路径),需用数组传参避免解析错误: Process process = Runtime.getRuntime().exec( new String[]{"cmd", "/c", "echo", "Hello World!"} );
推荐方法:ProcessBuilder
ProcessBuilder(Java 5+)提供更灵活的参数控制、环境变量管理和流重定向。
基础示例
try { // 构建命令及参数 ProcessBuilder builder = new ProcessBuilder( "cmd.exe", "/c", "ping", "www.baidu.com" ); // 重定向错误流到标准输出(便于统一处理) builder.redirectErrorStream(true); // 启动进程 Process process = builder.start(); // 读取输出 try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()) )) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } // 检查执行结果 int exitCode = process.waitFor(); if (exitCode == 0) { System.out.println("命令执行成功!"); } else { System.out.println("命令执行失败!Exit Code: " + exitCode); } } catch (IOException | InterruptedException e) { e.printStackTrace(); }
进阶功能
- 设置工作目录: builder.directory(new File("D:\project"));
- 环境变量管理: Map<String, String> env = builder.environment(); env.put("JAVA_HOME", "C:\Program Files\Java\jdk-17");
- 输出重定向到文件: builder.redirectOutput(new File("output.log"));
注意事项与最佳实践
-
流处理必须完整
未读取的输出流可能导致进程阻塞,始终处理getInputStream()(标准输出)和getErrorStream()(错误输出)。
-
超时控制
使用waitFor(long timeout, TimeUnit unit)避免无限等待:
if (!process.waitFor(30, TimeUnit.SECONDS)) { process.destroy(); // 强制终止进程 }
-
命令载入风险
禁止直接拼接用户输入到命令中!应使用参数化传递:
// 错误示例(高危!) String userInput = "malicious_command & rm -rf /"; Runtime.getRuntime().exec("cmd /c " + userInput); // 正确做法 ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "safe-command", userInput); -
跨平台兼容性

- Windows:命令前缀cmd /c
- Linux/Mac:使用/bin/sh -c或直接调用可执行文件 String command = System.getProperty("os.name").toLowerCase().contains("win") ? "cmd /c dir" : "/bin/ls";
-
异常处理
捕获IOException(命令不存在)和InterruptedException(进程中断)。
- 简单命令:优先使用Runtime.exec(),注意参数格式。
- 复杂任务:选择ProcessBuilder,尤其在需要环境控制、目录设置或流重定向时。
- 安全第一:严格校验外部输入,避免命令载入漏洞。
- Runtime.exec()
- ProcessBuilder
安全实践依据OWASP命令载入防护指南。
Runtime与ProcessBuilder对比
特性 Runtime.exec() ProcessBuilder 参数灵活性 需手动处理空格和引号 支持参数列表(更安全) 环境变量控制 无直接支持 可通过environment()修改 工作目录设置 不支持 支持directory() 流重定向 需手动编码 内置redirectOutput() 适用场景 简单命令 复杂流程或生产环境
通过合理选择API并遵循最佳实践,Java可高效安全地集成系统命令,适用于自动化部署、批处理等场景。
引用说明 参考Oracle官方文档:
