Java调用CMD命令如何实现?

核心方法

使用 Runtime 类(传统方式)

try {
    // 执行命令
    Process process = Runtime.getRuntime().exec("cmd /c dir C:\\");
    // 读取命令输出
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream(), "GBK")  // Windows中文环境用GBK编码
    );
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
    // 等待命令执行完成(阻塞当前线程)
    int exitCode = process.waitFor();
    System.out.println("Exit Code: " + exitCode);
} catch (Exception e) {
    e.printStackTrace();
}
  • 关键参数说明
    • cmd /c [命令]:执行后关闭CMD窗口(/k表示执行后保留窗口)。
    • process.getInputStream():获取命令的标准输出流。
    • process.waitFor():阻塞当前线程直到命令结束。

使用 ProcessBuilder 类(推荐方式)

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(), "GBK"))
    ) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }
    // 检查执行结果
    if (process.waitFor() == 0) {
        System.out.println("命令执行成功");
    } else {
        System.out.println("命令执行失败");
    }
} catch (Exception e) {
    e.printStackTrace();
}
  • 优势
    • 支持参数列表化(避免命令注入风险)。
    • 可设置工作目录、环境变量。
    • 灵活的重定向输入/输出/错误流。

关键注意事项

  1. 编码问题

    • Windows CMD默认使用GBK编码,Linux/Mac使用UTF-8,错误编码会导致输出乱码:
      new InputStreamReader(process.getInputStream(), "GBK")
  2. 阻塞与超时控制

    • process.waitFor()会无限期阻塞线程,建议使用带超时的版本:
      boolean finished = process.waitFor(10, TimeUnit.SECONDS);
      if (!finished) {
          process.destroy();  // 强制终止进程
      }
  3. 错误流处理

    • 必须同时读取标准输出流和错误流,否则进程可能因缓冲区满而挂起:
      // 分别启动两个线程读取stdout和stderr
      new Thread(() -> readStream(process.getInputStream())).start();
      new Thread(() -> readStream(process.getErrorStream())).start();
  4. 命令注入风险

    • 错误做法:拼接用户输入的字符串(高危!)
      Runtime.getRuntime().exec("cmd /c " + userInput);  // 可能执行恶意命令
    • 正确做法:使用ProcessBuilder分割参数:
      ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "echo", userInput);
  5. 跨平台兼容性

    • Linux/Mac需替换命令前缀:
      String[] command = System.getProperty("os.name").toLowerCase().contains("win") 
          ? new String[]{"cmd.exe", "/c", "dir"}
          : new String[]{"/bin/sh", "-c", "ls"};

完整示例:执行Python脚本并捕获输出

public class ExecuteCMD {
    public static void main(String[] args) {
        try {
            ProcessBuilder builder = new ProcessBuilder("python", "C:/test.py");
            builder.directory(new File("C:/"));  // 设置工作目录
            Process process = builder.start();
            // 异步读取输出
            StringBuilder output = new StringBuilder();
            Thread readThread = new Thread(() -> {
                try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))
                ) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        output.append(line).append("\n");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            readThread.start();
            // 等待命令结束
            int exitCode = process.waitFor();
            readThread.join();  // 确保输出读取完成
            System.out.println("输出内容:\n" + output);
            System.out.println("退出码: " + exitCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

安全与最佳实践

  1. 最小权限原则:避免以管理员权限执行命令。
  2. 资源释放:用try-with-resources确保流关闭。
  3. 日志记录:记录执行的命令、参数和退出码,便于审计。
  4. 输入验证:严格校验用户输入,禁止直接拼接命令。

引用说明

  • Oracle官方文档:ProcessBuilder, Runtime.exec()
  • 编码问题参考:The Pitfalls of Runtime.exec()
  • 安全建议:OWASP Command Injection

原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/7121.html

(0)
酷番叔酷番叔
上一篇 2025年7月12日 21:02
下一篇 2025年7月12日 21:41

相关推荐

  • 智慧旅游平台案例分析,谁是国内领军者?国内智慧旅游平台排名

    2026年国内智慧旅游平台服务商的核心竞争力已从单一的OTA流量分发转向“AI+大数据+沉浸式体验”的全链路数字化重构,其中携程、同程旅行及华为云构成的生态联盟在市场份额与技术壁垒上占据绝对主导,建议企业在选型时优先考虑具备自研大模型能力且拥有政府数据接口的头部服务商,行业格局演变:从流量竞争到算力博弈市场集中……

    2026年5月22日
    8700
  • 国内智能营销使用文档介绍,智能营销系统怎么使用

    国内智能营销的核心在于利用AI大模型实现从“流量获取”到“私域转化”的全链路自动化,2026年行业共识表明,其ROI(投资回报率)平均提升40%以上,关键在于数据合规与精准用户画像,智能营销的技术底座与核心逻辑随着2026年百度SEO标准向“内容价值+用户体验”深度倾斜,智能营销不再仅仅是工具的堆砌,而是基于A……

    2026年5月19日
    8500
  • 国内服务器操作系统好用么,国内服务器操作系统

    国内服务器操作系统在2026年已完全具备企业级可用性,尤其在信创合规、国产芯片适配及本地化技术支持方面表现优异,是替代国外产品的成熟选择,但在极高端通用计算场景下生态丰富度仍略逊于Linux主流发行版,核心优势:为何2026年值得选择国产OS?信创合规与政策红利随着国家信息安全战略的深入,政府、金融、能源等关键……

    2026年5月16日
    8500
  • 关系型数据库采集方法及其应用探讨?数据库采集技术有哪些

    关系型数据库的数据采集并非简单的“复制粘贴”,而是基于事务一致性(ACID)原则,通过CDC(变更数据捕获)、全量快照与增量日志解析相结合的混合架构,实现从源头到目标端的实时或近实时数据同步,在2026年的数据治理环境下,传统ETL工具已难以满足高并发、低延迟的业务需求,企业级数据采集的核心在于“无损”与“实时……

    2026年6月3日
    4800
  • 未来教育模式将如何革新?未来教育发展趋势及变革方向

    智能教育的核心本质是利用人工智能、大数据及物联网技术,重构“教、学、管、评”全流程,实现从标准化灌输向个性化自适应学习的范式转移,其2026年的主流形态已确认为“人机协同”的双师模式,智能教育的底层逻辑与技术演进从“数字化”到“智能化”的跨越传统的教育信息化主要解决资源触达问题,而2026年的智能教育则聚焦于认……

    2026年6月30日
    2700

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN

关注微信