JAVA remotely call Linux shell commands-complete the JAVA side to collect the Linx server disk, memory and other information and return it to the front end

package com.learn.service;
import com.jcraft.jsch.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * Remotely call Linux shell commands
 * @author yuyihao 2019.10.12
 */
public class LinuxStateForShell {
    public static final String CPU_MEM_SHELL = "top -b -n 1"; // liunx commands users to obtain system information
    public static final String FILES_SHELL = "df -hl"; // View disk usage
    public static final String[] COMMANDS = {CPU_MEM_SHELL, FILES_SHELL}; // command array
    /**
     * There are some escape characters in java, such as "\n" for newline characters, some operators that JDK comes with System.getProperty("line.separator");
     * This is also a newline character, and its function is the same as "\n". This method can distinguish the newline between Windows and Linux environments.
     * During development and not in the same environment, you can use System.getProperty("line.separator"); to control line break
     */
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
    private static Session session;

    /**
     * Connect to the specified HOST
     * @return isConnect
     * @throws JSchException JSchException
     */
    private static boolean connect(String user, String passwd, String host) {
        JSch jsch = new JSch();
        try {
            session = jsch.getSession(user, host, 22);
            session.setPassword(passwd);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
        } catch (JSchException e) {
            e.printStackTrace ();
            System.out.println("connect error !");
            return false;
        }
        return true;
    }

    /**
     * Remotely connect to the Linux server to execute related commands
     * Script executed by @param commands
     * @param user username for remote connection
     * @param passwd password for remote connection
     * @param host remote connection host IP
     * @return The final command returns information
     */
    public static Map<String, String> runDistanceShell(String[] commands, String user, String passwd, String host) throws IOException {
        if (!connect(user, passwd, host)) {
            return null;
        }
        Map<String, String> map = new HashMap<>();
        StringBuilder stringBuffer;
        BufferedReader reader = null;
        Channel channel = null;
        try {
            for (String command : commands) {
                stringBuffer = new StringBuilder();
                channel = session.openChannel("exec");
                ((ChannelExec) channel).setCommand(command);
                channel.setInputStream(null);
                ((ChannelExec) channel).setErrStream(System.err);
                channel.connect();
                InputStream in = channel.getInputStream();
                reader = new BufferedReader(new InputStreamReader(in));
                String buf;
                while ((buf = reader.readLine()) != null) {
                //Discard PID process information
                    if (buf.contains("PID")) {
                        break;
                    }
                    stringBuffer.append(buf.trim()).append(LINE_SEPARATOR);
                }
                //Each command stores its own return data-for subsequent processing of the return data
                map.put(command, stringBuffer.toString());
            }
        } catch (IOException | JSchException e) {
            e.printStackTrace ();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace ();
            }
            if (channel != null) {
                channel.disconnect();
            }
            session.disconnect();
        }
        return map;
    }

    /**
     * Process the information returned by the shell
     * The specific processing process is subject to the data format returned by the server
     * Different Linux versions return information in different formats
     * @param result information returned by shell
     * @return Final processed information
     */
    private static String disposeResultMessage(Map<String, String> result) {
        StringBuilder buffer = new StringBuilder();
        for (String command : COMMANDS) {
            String commandResult = result.get(command);
            if (null == commandResult) continue;
            if (command.equals(CPU_MEM_SHELL)) {
                String[] strings = commandResult.split(LINE_SEPARATOR);
                //Split the returned result by line break
                for (String line : strings) {
                    line = line.toUpperCase();//Transfer to uppercase
                    // Processing CPU Cpu (s): 10.8% us, 0.9% sy, 0.0% ni, 87.6% id, 0.7% wa, 0.0% hi, 0.0% si, 0.0% st
                    if (line.startsWith("CPU(S):")) {
                        String cpuStr = "CPU user share:";
                        try {
                            cpuStr += line.split(":")[1].split(",")[0].replace("US", "");
                        } catch (Exception e) {
                            e.printStackTrace ();
                            cpuStr += "Error during calculation";
                        }
                        buffer.append(cpuStr).append(LINE_SEPARATOR);
                    //Processing memory Mem: 66100704k total, 65323404k used, 777300k free, 89940k buffers
                    } else if (line.startsWith("MEM")) {
                        String memStr = "Memory usage:";
                        try {
                            memStr += line.split(":")[1]
                                    .replace("TOTAL", "总计")
                                    .replace("USED", "Used")
                                    .replace("FREE", "空闲")
                                    .replace("BUFFERS", "缓存");
                        } catch (Exception e) {
                            e.printStackTrace ();
                            memStr += "Error during calculation";
                            buffer.append(memStr).append(LINE_SEPARATOR);
                            continue;
                        }
                        buffer.append(memStr).append(LINE_SEPARATOR);
                    }
                }
            } else if (command.equals(FILES_SHELL)) {
                //Process system disk status
                buffer.append("System Disk Status:");
                try {
                    buffer.append(disposeFilesSystem(commandResult)).append(LINE_SEPARATOR);
                } catch (Exception e) {
                    e.printStackTrace ();
                    buffer.append("Error during calculation").append(LINE_SEPARATOR);
                }
            }
        }
        return buffer.toString();
    }
    //Process system disk status

    /**
     * @param commandResult handles the shell execution result of the system disk status
     * @return processed result
     */
    /**
     * Final processing result
     * CPU user share: 0.2%
     * Memory usage: 1020344K total, 160248K used, 860096K free, 14176K cache
     * System disk status: 7.66G in size, 2.93G in use, 4.73G in idle
     */
    private static String disposeFilesSystem(String commandResult) {
        String[] strings = commandResult.split(LINE_SEPARATOR);
        // final String PATTERN_TEMPLATE = "([a-zA-Z0-9%_/]*)\\s";
        Double size = 0d;
        Double used = 0d;
        for (int i = 1; i <strings.length; i++) {//No need for the first line title

            String[] row = strings[i].split("\\s+");

            size += disposeUnit(row[1]); // second column size

            used += disposeUnit(row[2]); // third column used
        }

        return new StringBuilder().append("大小 ").append(Math.round(size * 100)/100d).append("G , 已使用").append(Math.round(used * 100)/100d).append("G ,空闲")
                .append(Math.round((size - used) * 100)/100d).append("G").toString();
    }

    /**
     * Processing unit conversion
     * K/KB/M/T is finally converted to G for processing
     * @param s data string with unit
     * @return The processed value in G
     */
    private static Double disposeUnit(String s) {
        try {
            s = s.toUpperCase();
            String lastIndex = s.substring(s.length() - 1);
            String num = s.substring(0, s.length() - 1);
            Double parseInt = Double.parseDouble(num);
            if (lastIndex.equals("G")) {
                return parseInt;
            } else if (lastIndex.equals("T")) {
                return parseInt * 1024;
            } else if (lastIndex.equals("M")) {
                return parseInt / 1024;
            } else if (lastIndex.equals("K") || lastIndex.equals("KB")) {
                return parseInt / (1024 * 1024);
            }
        } catch (NumberFormatException e) {
            e.printStackTrace ();
            return 0d;
        }
        return 0d;
    }

    public static void main(String[] args) throws IOException {
        Map<String, String> result = runDistanceShell(COMMANDS, "root", "root123", "192.168.56.101");
        System.out.println(disposeResultMessage(result));
    }

}
The important thing is said three times! The data returned by the commands executed by different versions of Linux are different. The specific problems need to be analyzed in detail

The version of Linx used in this example:

top -b -n 1 data after execution

df -hl data after execution

 

 

Guess you like

Origin blog.csdn.net/a1_HelloWord/article/details/102528261