服务器执行命令或脚本的两种方式

目录

1、通过Runtime

2、通过ProcessBuilder 


在java开发中,有时候需要与操作系统的命令行交互,执行特定的CMD命令或脚本。

我们有如下两种方式来实现:

Java的Runtime类和ProcessBuilder类都允许Java程序启动一个新的进程并执行特定的命令,通过标准输入输出流进行数据交换。Runtime类适用于简单的命令执行,ProcessBuilder类则更加灵活,适用于复杂的命令和参数传递。

1、通过Runtime

Runtime类提供了exec()方法来执行CMD命令。该方法接收一个String类型的命令字符串,并返回一个Process对象,通过这个对象可以获取命令执行的结果。

public static void runtimeExec() {
        try {
            // 调用CMD命令
            String command = "jps -l";
            Process process = Runtime.getRuntime().exec(command);

            // 获取命令输出结果
            InputStream inputStream = process.getInputStream();
            // InputStream errorStream = process.getErrorStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 设置编码为GBK
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // 等待命令执行完成
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

输出结果如下

服务器执行命令或脚本的两种方式_第1张图片

简单看下Runtime源码:

 public Process exec(String command) throws IOException {
        return exec(command, null, null);
    }

public Process exec(String command, String[] envp, File dir)
        throws IOException {
        if (command.isEmpty())
            throw new IllegalArgumentException("Empty command");

        StringTokenizer st = new StringTokenizer(command);
        String[] cmdarray = new String[st.countTokens()];
        for (int i = 0; st.hasMoreTokens(); i++)
            cmdarray[i] = st.nextToken();
        return exec(cmdarray, envp, dir);
    }

// 可以看到也是通过ProcessBuilder对象去start的
public Process exec(String[] cmdarray, String[] envp, File dir)
        throws IOException {
        return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();
    }

 

2、通过ProcessBuilder 

public static void processBuilder() throws IOException, InterruptedException {
        ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "jps -l");

        //设置环境变量,初始值是当前进程环境的一个副本System.getenv()
      /*  Map env = pb.environment();
        env.put("key", "value");*/

        //设置工作目录
        pb.directory(new File("E:\\study\\shell"));

        //redirectErrorStream 属性默认值为false,意思是子进程的标准输出和错误输出被发送给两个独立的流,这些流可以通过 Process.getInputStream() 和 Process.getErrorStream() 方法来访问。
        //如果将值设置为 true,标准错误将与标准输出合并。这使得关联错误消息和相应的输出变得更容易。
        // 在此情况下,合并的数据可从 Process.getInputStream() 返回的流读取,而从 Process.getErrorStream() 返回的流读取将直接到达文件尾。
        pb.redirectErrorStream(true);
       /* File log = new File("E:\\study\\shell\\log.txt");
        pb.redirectOutput(ProcessBuilder.Redirect.to(log));*/

        //启动进程
        Process process = pb.start();
        // 获取命令输出结果
        InputStream inputStream = process.getInputStream();
        //InputStream errorStream = process.getErrorStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 设置编码为GBK
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }

        // 等待命令执行完成
        process.waitFor();
    }

输出结果:

服务器执行命令或脚本的两种方式_第2张图片

当我们需要调用服务的某些脚本时,我们一般使用ProcessBuilder来调用,更加灵活 

你可能感兴趣的:(java基础,windows)