使用Java获取linux和window序列号

 更新时间:2024年01月24日 15:45:30   作者:三省同学  
这篇文章主要为大家详细介绍了如何使用Java获取Windows和Linux系统上的CPU序列号、磁盘、mac地址等信息,感兴趣的小伙伴可以跟随小编一起学习一下

前言

获取系统序列号在Java中并不是一个直接支持的功能,因为Java语言本身并不提供直接访问硬件级别的信息,如CPU序列号。但是,我们可以使用一些平台特定的工具或命令来实现这一功能。下面我将展示如何使用Java获取Windows和Linux系统上的CPU序列号、磁盘、mac地址等信息,及使用Runtime.getRuntime().exec执行linux命令没反应问题解决。

代码

需要确保你的系统上安装了wmic工具。

/**
 * 获取cpu序列号
 *
 * @return 序列号
 */
public static String getCPUSerialNumber() {
    String sysName = System.getProperty("os.name");
    if (sysName.contains("Windows")) {//win
        String str = runCmd("wmic cpu get ProcessorId", 3);
        return str;
    } else if (sysName.contains("Linux")) {
        String str = runCmd("dmidecode |grep -A16 \"Processor Information$\"", "ID");
        if (str != null) {
            return str.substring(str.indexOf(":")).trim();
        }
    } else if (sysName.contains("Mac")) {
        String str = runCmd("system_profiler SPHardwareDataType", "Serial Number");
        if (str != null) {
            return str.substring(str.indexOf(":") + 1).trim();
        }
    }
    return "";
}

/**
 * 获取硬盘序列号
 *
 * @return 硬盘序列号
 */
public static String getHardDiskSerialNumber() {
    String sysName = System.getProperty("os.name");
    if (sysName.contains("Windows")) {//win
        String str = runCmd("wmic path win32_physicalmedia get serialnumber", 3);
        return str;
    } else if (sysName.contains("Linux")) {
        String str = runCmd("dmidecode |grep -A16 \"System Information$\"", "Serial Number");
        if (str != null) {
            return str.substring(str.indexOf(":")).trim();
        }
    } else if (sysName.contains("Mac")) {
        String str = runCmd("system_profiler SPStorageDataType", "Volume UUID");
        if (str != null) {
            return str.substring(str.indexOf(":") + 1).trim();
        }
    }
    return "";
}

/**
 * 运行命令
 *
 * @param cmd  命令
 * @param line 返回第几行结果,0返回所有
 * @return 结果
 */
public static String runCmd(String cmd, int line) {
    Process process;
    Scanner sc = null;
    StringBuffer sb = new StringBuffer();
    try {
        process = Runtime.getRuntime().exec(cmd);
        process.getOutputStream().close();
        sc = new Scanner(process.getInputStream());
        int i = 0;
        while (sc.hasNextLine()) {
            i++;
            String str = sc.nextLine();
            if (line <= 0) {
                sb.append(str).append("\r\n");
            } else if (i == line) {
                return str.trim();
            }
        }
        sc.close();
    } catch (Exception e) {


    } finally {
        IoUtils.close(sc);
    }
    return sb.toString();
}

/**
 * 运行cmd命令
 *
 * @param cmd    命令
 * @param substr 关键字
 * @return 包含关键字的行数
 */
public static String runCmd(String cmd, String substr) {
    Process process;
    Scanner sc = null;
    try {
        //ProcessBuilder 类提供了一种更灵活的方式来构建和执行外部进程。与 Runtime.exec() 相比,ProcessBuilder 允许你更细致地控制进程的执行环境。
//            ProcessBuilder pb = new ProcessBuilder(new String[]{"/bin/sh", "-c", cmd});
//            process = pb.start();
        //Runtime.getRuntime().exec(String cmd) 方法在 Java 中用于执行外部命令。
        process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});
//            process = Runtime.getRuntime().exec(cmd);
        process.getOutputStream().close();
        sc = new Scanner(process.getInputStream());
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            if (str != null && str.contains(substr)) {
                return str.trim();
            }
        }
        sc.close();
    } catch (Exception e) {

    } finally {
        IoUtils.close(sc);
    }
    return null;
}

/**
 * 获取mac地址
 *
 * @return mac 列表
 */
public static List<String> getMacList() {
    ArrayList<String> list = new ArrayList<>();
    StringBuilder sb = new StringBuilder();
    try {
        java.util.Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
        while (en.hasMoreElements()) {
            NetworkInterface iface = en.nextElement();
            List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
            for (InterfaceAddress addr : addrs) {
                InetAddress ip = addr.getAddress();
                if (ip.isLinkLocalAddress()) {//本地的不要
                    continue;
                }
                NetworkInterface network = NetworkInterface.getByInetAddress(ip);
                if (network == null) {
                    continue;
                }
                byte[] mac = network.getHardwareAddress();
                if (mac == null) {
                    continue;
                }

                sb.delete(0, sb.length());
                for (int i = 0; i < mac.length; i++) {
                    sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
                }
                if (!list.contains(sb.toString())) {
                    list.add(sb.toString());
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return list;
}

问题

process = Runtime.getRuntime().exec(cmd);

使用 Runtime.getRuntime().exec(String cmd) 时,Java 会尝试使用系统的默认 shell(例如 bash、sh、cmd 等)来执行该命令。因此,你可能会遇到一些与 shell 的语法和解析有关的问题,特别是在处理空格、管道符等特殊字符时。

解决

方法一:ProcessBuilder 是一个更现代和灵活的方法,用于构建和执行外部进程。它提供了更多的控制选项,可以更好地处理参数和特殊字符。

ProcessBuilder pb = new ProcessBuilder("yourCommand", "arg1", "arg2");  
Process p = pb.start();

方法二:将命令字符串分解为字符串数组,并将它们传递给 exec 方法。这样可以确保每个参数都被正确处理,而不会被视为命令的一部分。

process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});

-c表示cmd是一条命令,从而不会被截断

到此这篇关于使用Java获取linux和window序列号的文章就介绍到这了,更多相关Java获取序列号内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • RedisTemplate和Redisson的区别

    RedisTemplate和Redisson的区别

    本文主要介绍了RedisTemplate和Redisson的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • 使用Nexus搭建Maven私服的方法步骤

    使用Nexus搭建Maven私服的方法步骤

    这篇文章主要介绍了使用Nexus搭建Maven私服的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • nacos配置文件优先级过程

    nacos配置文件优先级过程

    这篇文章主要介绍了nacos配置文件优先级过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • SpringBoot整合模板引擎过程代码实例

    SpringBoot整合模板引擎过程代码实例

    这篇文章主要介绍了SpringBoot整合模板引擎过程代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java中多媒体文件上传及页面回显的操作代码

    Java中多媒体文件上传及页面回显的操作代码

    这篇文章主要介绍了Java中多媒体文件上传及页面回显的操作代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • redis实现队列的阻塞、延时、发布和订阅

    redis实现队列的阻塞、延时、发布和订阅

    本文主要介绍了redis实现队列的阻塞、延时、发布和订阅,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • MyBatis 源码分析 之SqlSession接口和Executor类

    MyBatis 源码分析 之SqlSession接口和Executor类

    mybatis框架在操作数据的时候,离不开SqlSession接口实例类的作用,下面通过本文给大家实例剖析MyBatis 源码分析之SqlSession接口和Executor类,需要的朋友参考下吧
    2017-02-02
  • Spring Data JPA实现动态查询的两种方法

    Spring Data JPA实现动态查询的两种方法

    本篇文章主要介绍了Spring Data JPA实现动态查询的两种方法,具有一定的参考价值,有兴趣的可以了解一下。
    2017-04-04
  • Java设计模式之责任链模式的示例详解

    Java设计模式之责任链模式的示例详解

    责任链模式是将链中的每一个节点看做是一个对象,每个节点处理的请求均不相同,且内部自动维护下一个节点对象,当一个请求从链式的首段发出时,会沿着链的路径依次传递给每一个节点对象。本文将通过示例和大家详细聊聊责任链模式,需要的可以参考一下
    2022-11-11
  • SpringMVC结合ajaxfileupload实现文件无刷新上传代码

    SpringMVC结合ajaxfileupload实现文件无刷新上传代码

    本篇文章主要介绍了SpringMVC结合ajaxfileupload实现文件无刷新上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-04-04

最新评论