使用Java獲取linux和window序列號
前言
獲取系統(tǒng)序列號在Java中并不是一個(gè)直接支持的功能,因?yàn)镴ava語言本身并不提供直接訪問硬件級別的信息,如CPU序列號。但是,我們可以使用一些平臺特定的工具或命令來實(shí)現(xiàn)這一功能。下面我將展示如何使用Java獲取Windows和Linux系統(tǒng)上的CPU序列號、磁盤、mac地址等信息,及使用Runtime.getRuntime().exec執(zhí)行l(wèi)inux命令沒反應(yīng)問題解決。
代碼
需要確保你的系統(tǒng)上安裝了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 "";
}
/**
* 運(yùn)行命令
*
* @param cmd 命令
* @param line 返回第幾行結(jié)果,0返回所有
* @return 結(jié)果
*/
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();
}
/**
* 運(yùn)行cmd命令
*
* @param cmd 命令
* @param substr 關(guān)鍵字
* @return 包含關(guān)鍵字的行數(shù)
*/
public static String runCmd(String cmd, String substr) {
Process process;
Scanner sc = null;
try {
//ProcessBuilder 類提供了一種更靈活的方式來構(gòu)建和執(zhí)行外部進(jìn)程。與 Runtime.exec() 相比,ProcessBuilder 允許你更細(xì)致地控制進(jìn)程的執(zhí)行環(huán)境。
// ProcessBuilder pb = new ProcessBuilder(new String[]{"/bin/sh", "-c", cmd});
// process = pb.start();
//Runtime.getRuntime().exec(String cmd) 方法在 Java 中用于執(zhí)行外部命令。
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) 時(shí),Java 會嘗試使用系統(tǒng)的默認(rèn) shell(例如 bash、sh、cmd 等)來執(zhí)行該命令。因此,你可能會遇到一些與 shell 的語法和解析有關(guān)的問題,特別是在處理空格、管道符等特殊字符時(shí)。
解決
方法一:ProcessBuilder 是一個(gè)更現(xiàn)代和靈活的方法,用于構(gòu)建和執(zhí)行外部進(jìn)程。它提供了更多的控制選項(xiàng),可以更好地處理參數(shù)和特殊字符。
ProcessBuilder pb = new ProcessBuilder("yourCommand", "arg1", "arg2");
Process p = pb.start();
方法二:將命令字符串分解為字符串?dāng)?shù)組,并將它們傳遞給 exec 方法。這樣可以確保每個(gè)參數(shù)都被正確處理,而不會被視為命令的一部分。
process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd});
-c表示cmd是一條命令,從而不會被截?cái)?/p>
到此這篇關(guān)于使用Java獲取linux和window序列號的文章就介紹到這了,更多相關(guān)Java獲取序列號內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中String.split()的最詳細(xì)源碼解讀及注意事項(xiàng)
以前經(jīng)常使用String.split()方法,但是從來沒有注意,下面這篇文章主要給大家介紹了關(guān)于Java中String.split()最詳細(xì)源碼解讀及注意事項(xiàng)的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
jdbc實(shí)現(xiàn)圖書館借閱系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了jdbc實(shí)現(xiàn)圖書館借閱系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
Java測試題 實(shí)現(xiàn)一個(gè)注冊功能過程解析
這篇文章主要介紹了Java測試題 實(shí)現(xiàn)一個(gè)注冊功能過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Spring?Boot?RestController接口輸出到終端的操作代碼
這篇文章主要介紹了Spring?Boot?RestController接口如何輸出到終端,使用?HttpServletResponse?類,可以在使用curl執(zhí)行?Spring?Boot?REST接口的同時(shí),在控制臺輸出一些信息,給運(yùn)維人員知道當(dāng)前命令執(zhí)行的狀態(tài),感興趣的朋友跟隨小編一起看看吧2023-09-09
JUC并發(fā)編程LinkedBlockingQueue隊(duì)列深入分析源碼
LinkedBlockingQueue 是一個(gè)可選有界阻塞隊(duì)列,這篇文章主要為大家詳細(xì)介紹了Java中LinkedBlockingQueue的實(shí)現(xiàn)原理與適用場景,感興趣的可以了解一下2023-04-04

