写点什么

Java 代码执行本地命令

作者:emanjusaka
  • 2024-03-18
    江苏
  • 本文字数:2781 字

    阅读完需:约 9 分钟

Java 代码执行本地命令

by emanjusaka from https://www.emanjusaka.top/2024/03/java-exec-local-command 彼岸花开可奈何

本文欢迎分享与聚合,全文转载请留下原文地址。


我们可以在命令行中执行各种命令,比如,创建文件、查看文件夹下文件、调用第三方工具等等。


如果想在 java 代码中执行命令应该怎么操作呢?我们有两种方式可以实现:


  • 通过 Runtime.getRuntime().exec 调用命令

  • 使用 ProcessBuilder 类来构建和执行命令

Runtime.getRuntime().exec

Runtime.getRuntime().exec()是 Java 中用于执行操作系统命令的方法。它允许你在 Java 程序中执行外部命令,并获取命令的输出和错误信息。


下面是使用 Runtime.getRuntime().exec()执行一个简单命令的步骤:


  1. 创建一个 Runtime 对象,通过调用 Runtime.getRuntime()方法获取。

  2. 调用 exec()方法,传入要执行的命令和参数。

  3. exec()方法返回一个 Process 对象,表示正在执行的进程。

  4. 使用 Process 对象的方法来获取输出、错误流和返回值。


    /**     * 执行本地命令     * 不支持管道和重定向机制     *     * @param command 命令     */
public static void executeLocalCommand(String command) { try { // 执行命令 Process process = Runtime.getRuntime().exec(command);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
String line; while ((line = reader.readLine()) != null) { log.info(command + ",命令执行结果:", line); }
while ((line = errorReader.readLine()) != null) { // 输出标准错误(stderr),标记为错误信息 if (line.startsWith("[ERROR]")) { log.error(command + ",命令执行错误:", line); } else { log.warn(command + ",[WARNING]" + line); } }
// 等待命令执行完成 int exitCode = process.waitFor(); if (exitCode != 0) { throw new ServiceException("执行命令失败!"); } } } catch (IOException | InterruptedException e) { Thread.currentThread().interrupt(); // 如果是InterruptedException,则重新设置中断状态 throw new RuntimeException(e); } log.info(command + ",命令执行成功"); }
复制代码


注意:该方法不支持 shell 的管道符和重定向机制。它只能分步执行命令,每个命令都是独立的进程。


在进程执行完成后,你应该调用 Process 对象的 waitFor()方法来等待进程结束,并获取进程的返回值。这样可以确保进程正常结束,并且你可以根据返回值进行进一步处理。


如果需要使用管道符和重定向机制,可以考虑使用 ProcessBuilder 类来构建和执行命令。

ProcessBuilder

ProcessBuilder 是 Java 中用于创建和控制操作系统进程的类。它比 Runtime.exec()更加强大,因为它可以处理命令行参数、错误流和输入流,并支持管道和重定向。


下面是使用 ProcessBuilder 执行一个简单命令的步骤:


  1. 创建一个 ProcessBuilder 对象,并传入要执行的命令和参数。

  2. 调用 start()方法启动进程。

  3. 使用 Process 对象的方法来获取输出、错误流和返回值。


下面是一个调用的示例:


package top.emanjusaka;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;
@SpringBootApplicationpublic class Application { public static void main(String[] args) { String[] command = { "ls", "-l" }; // 创建ProcessBuilder对象,并传入要执行的命令和参数 ProcessBuilder processBuilder = new ProcessBuilder(command);
// 启动进程 Process process = null; try { process = processBuilder.start(); // 获取输出流 try ( BufferedReader outputReader = new BufferedReader(new InputStreamReader(process.getInputStream())); BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));) { String line; while ((line = outputReader.readLine()) != null) { System.out.println(line); } while ((line = errorReader.readLine()) != null) { // 输出标准错误(stderr),标记为错误信息 if (line.startsWith("[ERROR]")) { System.out.println(command + ",命令执行错误:" + line); } else { System.out.println(command + ",[WARNING]" + line); } } // 等待进程执行完成,并获取返回值 int exitCode = process.waitFor(); System.out.println("Exit code: " + exitCode); } catch (IOException e) { throw new RuntimeException(e); } } catch (InterruptedException | IOException e) { throw new RuntimeException(e); } }}
复制代码


执行结果:



上述代码将执行 ls -l 命令,并将输出打印到控制台。你可以根据需要修改命令和参数来执行其他命令或传递不同的参数。


请注意,使用 ProcessBuilder 时需要注意以下几点:


  • ProcessBuilder 可以处理命令行参数,因此你可以通过将参数作为字符串数组传递给 ProcessBuilder 的构造函数来传递多个参数。

  • 你可以使用 redirectErrorStream(true)方法将错误流合并到输出流中,这样你就可以同时读取标准输出和错误输出。

  • 在进程执行完成后,你应该调用 Process 对象的 waitFor()方法来等待进程结束,并获取进程的返回值。这样可以确保进程正常结束,并且你可以根据返回值进行进一步处理。


本文原创,才疏学浅,如有纰漏,欢迎指正。如果本文对您有所帮助,欢迎点赞,并期待您的反馈交流,共同成长。

原文地址: https://www.emanjusaka.top/2024/03/java-exec-local-command

微信公众号:emanjusaka 的编程栈

用户头像

emanjusaka

关注

还未添加个人签名 2022-04-29 加入

分享技术,共同成长。一个编程菜鸟的升级打怪之路~

评论

发布
暂无评论
Java 代码执行本地命令_Java_emanjusaka_InfoQ写作社区