【笔记】Linux命令执行工具类

【笔记】Linux命令执行工具类

1.LinuxCommandUtils

Java主要通过Runtime和Process执行Linux命令,Process是Runtime.exec的返回值,可以用来对执行过程进行后续操作(获取结果、发送命令、等待结果)
1.如果Linux命令需要执行很长时间,需要调用Process的waitFor方法,等待后台任务执行完毕,否则其会自动退出
2.waitFor方法可以设置超时时间,防止一直等待
3.执行需要特定环境变量的命令时,可以使用ProcessBuilder的getEnvironment
4.执行多个命令组合时需要使用{“/bin/sh”, cmd}

package com.sisyphus.util;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/*
* Java主要通过Runtime和Process执行Linux命令,Process是Runtime.exec的返回值,可以用来对执行过程进行后续操作(获取结果、发送命令、等待结果)
* 1.如果Linux命令需要执行很长时间,需要调用Process的waitFor方法,等待后台任务执行完毕,否则其会自动退出
* 2.waitFor方法可以设置超时时间,防止一直等待
* 3.执行需要特定环境变量的命令时,可以使用ProcessBuilder的getEnvironment
* 4.执行多个命令组合时需要使用{"/bin/sh", cmd}
* */
public class LinuxCommandUtils {
    /*
     * 2022-9-2
     * 【服务器执行Linux命令方法】
     * commands:需要执行的命令行
     * 【return】:命令的执行后,系统返回的信息
     * 【方法调用样例】:
     * List<String> commands = new ArrayList<>();
     * commands.add("cd /home/app");
     * commands.add("touch test.txt");
     * LinuxCommandUtils.executeCommands(commands);
     * */
    public static List<String> executeCommands(List<String> commands){
        List<String> rspList = new ArrayList<>();
        Runtime run = Runtime.getRuntime();
        try {
            Process proc = run.exec("/bin/bash", null, null);
            if(proc != null){
                BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
                for(String line : commands){
                    System.out.println("执行命令行:" + line);
                    out.println(line);
                }
                out.println("exit");    //这个命令必须执行,否则in流不结束
                System.out.println("exit成功执行");
                String rspLine = "";
                while((rspLine = in.readLine()) != null){
                    System.out.println("系统返回结果:" + rspLine);
                    rspList.add(rspLine);
                }
                System.out.println("proc等待中...");
                proc.waitFor();
                System.out.println("proc等待结束...");
                in.close();;
                out.close();
                proc.destroy();
            }else{
                System.out.println("proc为空");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return rspList;
    }
}

2.Runtime

每个Java应用程序都有一个Runtime类的Runtime ,允许应用程序与运行应用程序的环境进行接口,比如返回Java虚拟机中的可用内存量、返回Java虚拟机中的内存总量,以及运行垃圾回收器等等

应用程序无法创建自己的此类的实例,当前运行时可以从getRuntime方法获得

3.Process

ProcessBuilder.start()和Runtime.exec方法创建一个本机进程并返回一个Process子类的Process ,可以用来控制进程并获取有关它的信息。 Process类提供了用于执行进程输入,执行到进程的输出,等待进程完成,检查进程的退出状态以及破坏(杀死)进程的方法

创建进程的方法可能不适用于某些本机平台上的特殊进程,例如本机窗口进程,守护进程,Microsoft Windows上的Win16 / DOS进程或shell脚本

默认情况下,创建的子进程没有自己的终端或控制台。 其所有的标准I / O(即标准输入,标准输出,标准错误)操作将被重定向到父进程,在那里他们可以经由使用所述方法获得的流进行访问getOutputStream() , getInputStream()和getErrorStream() 。 父进程使用这些流将输入提供给子进程并从子进程获取输出。 因为一些本地平台只为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞甚至死锁

所有方法
在这里插入图片描述

4.PrintWriter

将对象的格式表示打印到文本输出流。 这个类实现了全部在发现print种方法PrintStream 。 它不包含用于编写原始字节的方法,程序应使用未编码的字节流

不像PrintStream类,如果启用自动刷新,它只会在调用的println,printf,或format方法来完成,而不是当一个换行符恰好是输出。 这些方法使用平台自己的行分隔符而不是换行符

这个类中的方法不会抛出I/O异常,尽管它的一些构造函数可能。 客户可以通过调用checkError()查询是否发生错误

构造方法
在这里插入图片描述
可见我们使用的构造方法是PrintWriter(OutputStream out, boolean autoFlush),那么这个autoFlush是什么意思呢?
简单来说,如果不开启autoFlush,那么只有当缓冲区满了,才会将内容输出,如果一直没有内容输入到缓冲区,或者内容无法装满缓冲区,线程就会一直阻塞在这里

题外话
与BufferedWriter的对比:

  • BufferedWriter:将文本写入字符输出流,缓冲各个字符从而提供单个字符、数组和字符串的高效写入。通过write()方法可以将获取到的字符输出,然后通过newLine()进行操作。并且BufferedWriter只能对字符流进行操作
  • PrintWriter:相对于BufferedWriter的好处在于,如果PrintWriter开启了自动刷新,那么当PrintWriter调用println、printf、format方法时,输出流中的数据就会自动刷新出去。PrintWriter不但能接收字符流,也能接收字节流

更细节方面的不同:

  1. PrintWriter的print、println方法可以接受任意类型的参数,而BufferedWriter的write方法只能接受字符、字符数组和字符串
  2. PrintWriter的println方法自动添加换行,BufferedWriter需要显式调用newLine()方法
  3. PrintWriter的方法不会抛异常,若关心异常,需要调用checkError()方法查看是否有异常发生
  4. PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

313YPHU3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值