Java与操作系统常用命令交互全解析
第一章:Java执行操作系统命令的核心API
1.1 Runtime.exec() 方法详解
Runtime.exec() 是Java执行外部命令最直接的方式,有6个重载版本:
java
// 最常用的四种形式 public Process exec(String command) public Process exec(String[] cmdarray) public Process exec(String command, String[] envp) public Process exec(String[] cmdarray, String[] envp) public Process exec(String command, String[] envp, File dir) public Process exec(String[] cmdarray, String[] envp, File dir)
基本使用示例:
java
import java.io.*; public class RuntimeExecExample { public static void main(String[] args) { try { // 执行简单命令 Process process = Runtime.getRuntime().exec("ls -la"); // 读取命令输出 BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()) ); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待命令执行完成 int exitCode = process.waitFor(); System.out.println("Exit code: " + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }1.2 ProcessBuilder 类详解
ProcessBuilder 提供了更灵活、更安全的命令执行方式:
java
public class ProcessBuilderExample { public static void main(String[] args) { try { // 创建ProcessBuilder实例 ProcessBuilder pb = new ProcessBuilder(); // 设置命令和参数(推荐方式,避免注入风险) pb.command("ls", "-la", "/home"); // 设置工作目录 pb.directory(new File("/home/user")); // 重定向错误流到标准输出 pb.redirectErrorStream(true); // 环境变量操作 Map<String, String> env = pb.environment(); env.put("JAVA_HOME", "/usr/lib/jvm/java-11"); env.put("PATH", env.get("PATH") + ":/usr/local/bin"); // 启动进程 Process process = pb.start(); // 处理输出 try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } // 获取退出码 int exitCode = process.waitFor(); System.out.println("Process exited with code: " + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }第二章:跨平台命令执行解决方案
2.1 平台检测与适配
java
public class PlatformUtils { public enum OS { WINDOWS, LINUX, MAC, SOLARIS, UNKNOWN } public static OS getOperatingSystem() { String osName = System.getProperty("os.name").toLowerCase(); if (osName.contains("win")) { return OS.WINDOWS; } else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) { return OS.LINUX; } else if (osName.contains("mac")) { return OS.MAC; } else if (osName.contains("sunos")) { return OS.SOLARIS; } else { return OS.UNKNOWN; } } public static String getShell() { OS os = getOperatingSystem(); switch (os) { case WINDOWS: return "cmd.exe"; case LINUX: case MAC: case SOLARIS: return "/bin/bash"; default: return "/bin/sh"; } } public static String[] buildCommand(String command) { OS os = getOperatingSystem(); if (os == OS.WINDOWS) { return new String[]{"cmd.exe", "/c", command}; } else { return new String[]{"/bin/bash", "-c", command}; } } }2.2 通用命令执行器实现
java
public class CommandExecutor { /** * 执行命令并返回结果 */ public static CommandResult execute(String command) throws IOException, InterruptedException { return execute(command, null, null); } /** * 执行命令(带环境变量和工作目录) */ public static CommandResult execute(String command, Map<String, String> env, File workingDir) throws IOException, InterruptedException { ProcessBuilder pb = new ProcessBuilder(); // 根据平台构建命令 String[] cmdArray = PlatformUtils.buildCommand(command); pb.command(cmdArray); // 设置环境变量 if (env != null && !env.isEmpty()) { Map<String, String> processEnv = pb.environment(); processEnv.putAll(env); } // 设置工作目录 if (workingDir != null) { pb.directory(workingDir); } // 重定向错误流 pb.redirectErrorStream(true); // 启动进程 Process process = pb.start(); // 读取输出 StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream())); BufferedReader errorReader = new BufferedReader( new InputStreamReader(process.getErrorStream()))) { // 读取标准输出 String line; while ((line = reader.readLine()) != null) { output.append(line).append(System.lineSeparator()); } // 读取错误输出 while ((line = errorReader.readLine()) != null) { error.append(line).append(System.lineSeparator()); } } // 等待进程结束 int exitCode = process.waitFor(); return new CommandResult(exitCode, output.toString(), error.toString()); } /** * 异步执行命令 */ public static CompletableFuture<CommandResult> executeAsync(String command) { return CompletableFuture.supplyAsync(() -> { try { return execute(command); } catch (IOException | InterruptedException e) { throw new RuntimeException("Command execution failed", e); } }); } /** * 命令执行结果封装类 */ public static class CommandResult { private final int exitCode; private final String output; private final String error; public CommandResult(int exitCode, String output, String error) { this.exitCode = exitCode; this.output = output; this.error = error; } // Getter方法 public int getExitCode() { return exitCode; } public String getOutput() { return output; } public String getError() { return error; } public boolean isSuccess() { return exitCode == 0; } } }第三章:常用操作系统命令分类实现
3.1 文件系统操作命令
java
public class FileSystemCommands { /** * 列出目录内容(跨平台) */ public static List<String> listDirectory(String path) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = "dir \"" + path + "\""; } else { command = "ls -la \"" + path + "\""; } CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { return Arrays.asList(result.getOutput().split(System.lineSeparator())); } else { throw new IOException("Failed to list directory: " + result.getError()); } } /** * 复制文件或目录 */ public static boolean copy(String source, String destination) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = "copy \"" + source + "\" \"" + destination + "\""; } else { command = "cp -r \"" + source + "\" \"" + destination + "\""; } CommandResult result = CommandExecutor.execute(command); return result.isSuccess(); } /** * 删除文件或目录 */ public static boolean delete(String path, boolean recursive) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { if (recursive) { command = "rmdir /s /q \"" + path + "\""; } else { command = "del \"" + path + "\""; } } else { if (recursive) { command = "rm -rf \"" + path + "\""; } else { command = "rm \"" + path + "\""; } } CommandResult result = CommandExecutor.execute(command); return result.isSuccess(); } /** * 创建目录 */ public static boolean createDirectory(String path, boolean createParent) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { if (createParent) { command = "mkdir \"" + path + "\""; } else { command = "mkdir \"" + path + "\""; } } else { if (createParent) { command = "mkdir -p \"" + path + "\""; } else { command = "mkdir \"" + path + "\""; } } CommandResult result = CommandExecutor.execute(command); return result.isSuccess(); } /** * 获取文件信息 */ public static Map<String, String> getFileInfo(String filePath) throws IOException, InterruptedException { Map<String, String> info = new HashMap<>(); if (PlatformUtils.getOperatingSystem() != PlatformUtils.OS.WINDOWS) { // Linux/Mac系统使用stat命令 String command = "stat \"" + filePath + "\""; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (String line : lines) { if (line.contains("Size:")) { info.put("size", line.split(":")[1].trim()); } else if (line.contains("Access:")) { info.put("permissions", line.split(":")[1].trim()); } else if (line.contains("Modify:")) { info.put("modified", line.split(":")[1].trim()); } } } } return info; } }3.2 系统信息查询命令
java
public class SystemInfoCommands { /** * 获取系统内存信息 */ public static MemoryInfo getMemoryInfo() throws IOException, InterruptedException { MemoryInfo info = new MemoryInfo(); if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { // Windows系统 String command = "wmic OS get TotalVisibleMemorySize,FreePhysicalMemory /value"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (String line : lines) { if (line.startsWith("TotalVisibleMemorySize=")) { info.totalMemory = Long.parseLong(line.split("=")[1].trim()) * 1024; } else if (line.startsWith("FreePhysicalMemory=")) { info.freeMemory = Long.parseLong(line.split("=")[1].trim()) * 1024; } } info.usedMemory = info.totalMemory - info.freeMemory; } } else { // Linux/Mac系统 String command = "free -b"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); if (lines.length > 1) { String[] memLine = lines[1].split("\\s+"); if (memLine.length >= 6) { info.totalMemory = Long.parseLong(memLine[1]); info.usedMemory = Long.parseLong(memLine[2]); info.freeMemory = Long.parseLong(memLine[3]); } } } } return info; } /** * 获取CPU信息 */ public static CpuInfo getCpuInfo() throws IOException, InterruptedException { CpuInfo info = new CpuInfo(); if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { String command = "wmic cpu get NumberOfCores,NumberOfLogicalProcessors,Name /value"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (String line : lines) { if (line.startsWith("NumberOfCores=")) { info.cores = Integer.parseInt(line.split("=")[1].trim()); } else if (line.startsWith("NumberOfLogicalProcessors=")) { info.logicalProcessors = Integer.parseInt(line.split("=")[1].trim()); } else if (line.startsWith("Name=")) { info.model = line.split("=")[1].trim(); } } } } else { String command = "lscpu"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (String line : lines) { if (line.startsWith("CPU(s):")) { info.logicalProcessors = Integer.parseInt(line.split(":")[1].trim()); } else if (line.startsWith("Model name:")) { info.model = line.split(":")[1].trim(); } else if (line.startsWith("Core(s) per socket:")) { info.coresPerSocket = Integer.parseInt(line.split(":")[1].trim()); } } } } return info; } /** * 获取磁盘使用情况 */ public static List<DiskInfo> getDiskInfo() throws IOException, InterruptedException { List<DiskInfo> disks = new ArrayList<>(); if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { String command = "wmic logicaldisk get size,freespace,caption"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (int i = 1; i < lines.length; i++) { String[] parts = lines[i].trim().split("\\s+"); if (parts.length >= 3) { DiskInfo disk = new DiskInfo(); disk.drive = parts[0]; disk.totalSpace = Long.parseLong(parts[1]); disk.freeSpace = Long.parseLong(parts[2]); disks.add(disk); } } } } else { String command = "df -B1"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (int i = 1; i < lines.length; i++) { String[] parts = lines[i].trim().split("\\s+"); if (parts.length >= 6) { DiskInfo disk = new DiskInfo(); disk.filesystem = parts[0]; disk.totalSpace = Long.parseLong(parts[1]); disk.usedSpace = Long.parseLong(parts[2]); disk.freeSpace = Long.parseLong(parts[3]); disk.mountPoint = parts[5]; disks.add(disk); } } } } return disks; } /** * 信息封装类 */ public static class MemoryInfo { public long totalMemory; public long usedMemory; public long freeMemory; public double getUsedPercentage() { return totalMemory > 0 ? (double) usedMemory / totalMemory * 100 : 0; } } public static class CpuInfo { public String model; public int cores; public int logicalProcessors; public int coresPerSocket; } public static class DiskInfo { public String drive; public String filesystem; public String mountPoint; public long totalSpace; public long usedSpace; public long freeSpace; public double getUsagePercentage() { return totalSpace > 0 ? (double) usedSpace / totalSpace * 100 : 0; } } }3.3 进程管理命令
java
public class ProcessManagementCommands { /** * 获取进程列表 */ public static List<ProcessInfo> getProcessList() throws IOException, InterruptedException { List<ProcessInfo> processes = new ArrayList<>(); if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { String command = "wmic process get ProcessId,Name,CommandLine /format:csv"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (String line : lines) { if (line.contains("Node,")) continue; // 跳过标题行 String[] parts = line.split(","); if (parts.length >= 4) { ProcessInfo info = new ProcessInfo(); info.pid = Integer.parseInt(parts[parts.length - 3].trim()); info.name = parts[parts.length - 2].trim(); info.commandLine = parts[parts.length - 1].trim(); processes.add(info); } } } } else { String command = "ps aux"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String[] lines = result.getOutput().split(System.lineSeparator()); for (int i = 1; i < lines.length; i++) { String[] parts = lines[i].trim().split("\\s+", 11); if (parts.length >= 11) { ProcessInfo info = new ProcessInfo(); info.user = parts[0]; info.pid = Integer.parseInt(parts[1]); info.cpu = Float.parseFloat(parts[2]); info.memory = Float.parseFloat(parts[3]); info.command = parts[10]; processes.add(info); } } } } return processes; } /** * 终止进程 */ public static boolean killProcess(int pid, boolean force) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { if (force) { command = "taskkill /F /PID " + pid; } else { command = "taskkill /PID " + pid; } } else { if (force) { command = "kill -9 " + pid; } else { command = "kill " + pid; } } CommandResult result = CommandExecutor.execute(command); return result.isSuccess(); } /** * 查找特定进程 */ public static List<ProcessInfo> findProcessByName(String name) throws IOException, InterruptedException { List<ProcessInfo> allProcesses = getProcessList(); List<ProcessInfo> foundProcesses = new ArrayList<>(); for (ProcessInfo process : allProcesses) { if (process.name.toLowerCase().contains(name.toLowerCase()) || process.command.toLowerCase().contains(name.toLowerCase())) { foundProcesses.add(process); } } return foundProcesses; } /** * 进程信息封装类 */ public static class ProcessInfo { public int pid; public String name; public String user; public float cpu; public float memory; public String command; public String commandLine; @Override public String toString() { return String.format("PID: %d, Name: %s, CPU: %.1f%%, Memory: %.1f%%", pid, name, cpu, memory); } } }3.4 网络相关命令
java
public class NetworkCommands { /** * 测试网络连接 */ public static boolean ping(String host, int timeoutSeconds) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = String.format("ping -n 1 -w %d %s", timeoutSeconds * 1000, host); } else { command = String.format("ping -c 1 -W %d %s", timeoutSeconds, host); } CommandResult result = CommandExecutor.execute(command); return result.isSuccess() && result.getOutput().contains("bytes from"); } /** * 获取网络接口信息 */ public static List<NetworkInterfaceInfo> getNetworkInterfaces() throws IOException, InterruptedException { List<NetworkInterfaceInfo> interfaces = new ArrayList<>(); if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { String command = "ipconfig /all"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { // 解析Windows ipconfig输出 // 实现略,根据需要添加解析逻辑 } } else { String command = "ifconfig -a"; CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { // 解析Linux/Mac ifconfig输出 // 实现略,根据需要添加解析逻辑 } } return interfaces; } /** * 端口检测 */ public static boolean isPortOpen(String host, int port, int timeout) throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = String.format("powershell Test-NetConnection -ComputerName %s -Port %d -InformationLevel Quiet", host, port); } else { command = String.format("timeout %d bash -c '</dev/tcp/%s/%d && echo open || echo closed'", timeout, host, port); } CommandResult result = CommandExecutor.execute(command); return result.getOutput().contains("open"); } /** * 获取路由表 */ public static String getRoutingTable() throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = "route print"; } else { command = "netstat -rn"; } CommandResult result = CommandExecutor.execute(command); return result.getOutput(); } /** * 网络接口信息封装类 */ public static class NetworkInterfaceInfo { public String name; public String macAddress; public List<String> ipAddresses; public long bytesReceived; public long bytesSent; public boolean isUp; } }第四章:高级应用与最佳实践
4.1 流式命令输出处理
java
public class StreamingCommandExecutor { /** * 实时流式处理命令输出 */ public static void executeWithStreaming(String command, Consumer<String> outputConsumer, Consumer<String> errorConsumer) throws IOException, InterruptedException { ProcessBuilder pb = new ProcessBuilder(PlatformUtils.buildCommand(command)); pb.redirectErrorStream(false); Process process = pb.start(); // 启动输出读取线程 Thread outputThread = new Thread(() -> { try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { outputConsumer.accept(line); } } catch (IOException e) { e.printStackTrace(); } }); // 启动错误读取线程 Thread errorThread = new Thread(() -> { try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getErrorStream()))) { String line; while ((line = reader.readLine()) != null) { errorConsumer.accept(line); } } catch (IOException e) { e.printStackTrace(); } }); outputThread.start(); errorThread.start(); // 等待进程结束 int exitCode = process.waitFor(); // 等待读取线程结束 outputThread.join(); errorThread.join(); System.out.println("Command exited with code: " + exitCode); } /** * 示例:实时监控日志文件 */ public static void tailLogFile(String logPath, int lines) throws Exception { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = String.format("powershell Get-Content %s -Tail %d -Wait", logPath, lines); } else { command = String.format("tail -f -n %d %s", lines, logPath); } executeWithStreaming(command, line -> System.out.println("[LOG] " + line), error -> System.err.println("[ERROR] " + error) ); } }4.2 命令执行超时控制
java
public class TimeoutCommandExecutor { /** * 带超时控制的命令执行 */ public static CommandResult executeWithTimeout(String command, long timeout, TimeUnit unit) throws IOException, InterruptedException, TimeoutException { ProcessBuilder pb = new ProcessBuilder(PlatformUtils.buildCommand(command)); pb.redirectErrorStream(true); Process process = pb.start(); // 读取输出的Future CompletableFuture<String> outputFuture = CompletableFuture.supplyAsync(() -> { try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { StringBuilder output = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { output.append(line).append(System.lineSeparator()); } return output.toString(); } catch (IOException e) { throw new RuntimeException(e); } }); // 等待进程结束的Future CompletableFuture<Integer> exitCodeFuture = CompletableFuture.supplyAsync(() -> { try { return process.waitFor(); } catch (InterruptedException e) { throw new RuntimeException(e); } }); try { // 等待超时 String output = outputFuture.get(timeout, unit); int exitCode = exitCodeFuture.get(timeout, unit); return new CommandResult(exitCode, output, ""); } catch (TimeoutException e) { // 超时后销毁进程 process.destroyForcibly(); throw new TimeoutException("Command execution timed out after " + timeout + " " + unit); } catch (ExecutionException e) { throw new IOException("Command execution failed", e.getCause()); } } }4.3 安全最佳实践
java
public class SecureCommandExecutor { /** * 安全的命令执行(防止命令注入) */ public static CommandResult executeSecure(String[] cmdArray, Map<String, String> env, File workingDir) throws IOException, InterruptedException { // 验证命令参数 validateCommand(cmdArray); ProcessBuilder pb = new ProcessBuilder(); pb.command(cmdArray); if (env != null) { // 清理环境变量 Map<String, String> safeEnv = sanitizeEnvironment(env); pb.environment().putAll(safeEnv); } if (workingDir != null) { // 验证工作目录 validateWorkingDirectory(workingDir); pb.directory(workingDir); } // 设置资源限制 pb.redirectErrorStream(true); return CommandExecutor.execute(String.join(" ", cmdArray), env != null ? env : new HashMap<>(), workingDir); } private static void validateCommand(String[] cmdArray) throws IOException { if (cmdArray == null || cmdArray.length == 0) { throw new IOException("Command array cannot be null or empty"); } // 检查命令是否存在(Linux/Mac) if (PlatformUtils.getOperatingSystem() != PlatformUtils.OS.WINDOWS) { String command = cmdArray[0]; if (!command.startsWith("/")) { // 相对路径命令,检查是否在PATH中 String whichCommand = "which " + command; try { CommandResult result = CommandExecutor.execute(whichCommand); if (!result.isSuccess()) { throw new IOException("Command not found: " + command); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IOException("Command validation interrupted", e); } } } } private static Map<String, String> sanitizeEnvironment(Map<String, String> env) { Map<String, String> safeEnv = new HashMap<>(); for (Map.Entry<String, String> entry : env.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); // 过滤危险的变量名 if (!isDangerousEnvVar(key)) { // 清理变量值 safeEnv.put(key, sanitizeString(value)); } } return safeEnv; } private static boolean isDangerousEnvVar(String varName) { String[] dangerousVars = {"PATH", "LD_LIBRARY_PATH", "LD_PRELOAD", "IFS"}; return Arrays.asList(dangerousVars).contains(varName); } private static String sanitizeString(String input) { // 移除危险字符 return input.replaceAll("[;&|$`]", ""); } private static void validateWorkingDirectory(File dir) throws IOException { if (!dir.exists()) { throw new IOException("Working directory does not exist: " + dir.getPath()); } if (!dir.isDirectory()) { throw new IOException("Path is not a directory: " + dir.getPath()); } if (!dir.canRead()) { throw new IOException("Cannot read working directory: " + dir.getPath()); } } }第五章:实战应用示例
5.1 系统监控工具实现
java
public class SystemMonitor { private ScheduledExecutorService scheduler; private Map<String, List<Double>> metricsHistory; public SystemMonitor() { scheduler = Executors.newScheduledThreadPool(2); metricsHistory = new HashMap<>(); } /** * 开始监控 */ public void startMonitoring(long interval, TimeUnit unit) { scheduler.scheduleAtFixedRate(this::collectMetrics, 0, interval, unit); scheduler.scheduleAtFixedRate(this::reportMetrics, interval, interval, unit); } /** * 收集系统指标 */ private void collectMetrics() { try { // 收集CPU使用率 double cpuUsage = getCpuUsage(); addMetric("cpu.usage", cpuUsage); // 收集内存使用率 SystemInfoCommands.MemoryInfo memInfo = SystemInfoCommands.getMemoryInfo(); double memUsage = memInfo.getUsedPercentage(); addMetric("memory.usage", memUsage); // 收集磁盘使用率 List<SystemInfoCommands.DiskInfo> disks = SystemInfoCommands.getDiskInfo(); for (SystemInfoCommands.DiskInfo disk : disks) { double diskUsage = disk.getUsagePercentage(); addMetric("disk." + disk.drive + ".usage", diskUsage); } } catch (Exception e) { System.err.println("Failed to collect metrics: " + e.getMessage()); } } /** * 获取CPU使用率 */ private double getCpuUsage() throws IOException, InterruptedException { String command; if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { command = "wmic cpu get loadpercentage /value"; } else { command = "top -bn1 | grep 'Cpu(s)' | awk '{print $2}'"; } CommandResult result = CommandExecutor.execute(command); if (result.isSuccess()) { String output = result.getOutput(); if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { String[] lines = output.split(System.lineSeparator()); for (String line : lines) { if (line.startsWith("LoadPercentage=")) { return Double.parseDouble(line.split("=")[1].trim()); } } } else { // 解析top命令输出 return Double.parseDouble(output.replace("%", "").trim()); } } return 0.0; } private void addMetric(String key, double value) { metricsHistory.computeIfAbsent(key, k -> new ArrayList<>()).add(value); // 保持最近100个值 List<Double> history = metricsHistory.get(key); if (history.size() > 100) { history.remove(0); } } /** * 报告指标 */ private void reportMetrics() { System.out.println("\n=== System Metrics Report ==="); System.out.println("Time: " + new Date()); for (Map.Entry<String, List<Double>> entry : metricsHistory.entrySet()) { String key = entry.getKey(); List<Double> values = entry.getValue(); if (!values.isEmpty()) { double current = values.get(values.size() - 1); double avg = values.stream().mapToDouble(Double::doubleValue).average().orElse(0); double max = values.stream().mapToDouble(Double::doubleValue).max().orElse(0); System.out.printf("%s: Current=%.1f%%, Avg=%.1f%%, Max=%.1f%%%n", key, current, avg, max); } } System.out.println("=============================\n"); } /** * 停止监控 */ public void stop() { scheduler.shutdown(); try { if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) { scheduler.shutdownNow(); } } catch (InterruptedException e) { scheduler.shutdownNow(); Thread.currentThread().interrupt(); } } }5.2 批量命令执行器
java
public class BatchCommandExecutor { /** * 批量执行命令 */ public static List<CommandResult> executeBatch(List<String> commands, int maxConcurrent) throws InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(maxConcurrent); List<CompletableFuture<CommandResult>> futures = new ArrayList<>(); for (String command : commands) { CompletableFuture<CommandResult> future = CompletableFuture.supplyAsync(() -> { try { return CommandExecutor.execute(command); } catch (IOException | InterruptedException e) { return new CommandResult(-1, "", e.getMessage()); } }, executor); futures.add(future); } // 等待所有命令完成 CompletableFuture<Void> allFutures = CompletableFuture.allOf( futures.toArray(new CompletableFuture[0]) ); allFutures.join(); executor.shutdown(); // 收集结果 List<CommandResult> results = new ArrayList<>(); for (CompletableFuture<CommandResult> future : futures) { try { results.add(future.get()); } catch (ExecutionException e) { results.add(new CommandResult(-1, "", e.getMessage())); } } return results; } /** * 从文件读取命令并执行 */ public static List<CommandResult> executeFromFile(String commandFile) throws IOException, InterruptedException { List<String> commands = Files.readAllLines(Paths.get(commandFile)); commands.removeIf(line -> line.trim().isEmpty() || line.trim().startsWith("#")); return executeBatch(commands, Runtime.getRuntime().availableProcessors()); } }第六章:常见问题与调试技巧
6.1 常见问题解决
java
public class TroubleshootingGuide { /** * 诊断命令执行问题 */ public static void diagnoseCommandExecution(String command) { System.out.println("Diagnosing command: " + command); try { // 1. 检查命令是否存在 if (!isCommandAvailable(command)) { System.err.println("ERROR: Command not found or not executable"); return; } // 2. 测试简单执行 ProcessBuilder pb = new ProcessBuilder(PlatformUtils.buildCommand("echo test")); Process process = pb.start(); int exitCode = process.waitFor(); if (exitCode != 0) { System.err.println("ERROR: Basic command execution failed"); return; } // 3. 测试目标命令 pb = new ProcessBuilder(PlatformUtils.buildCommand(command)); pb.redirectErrorStream(true); process = pb.start(); // 读取输出 try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { System.out.println("Command output:"); String line; while ((line = reader.readLine()) != null) { System.out.println(" " + line); } } exitCode = process.waitFor(); System.out.println("Exit code: " + exitCode); } catch (IOException | InterruptedException e) { System.err.println("Exception: " + e.getMessage()); e.printStackTrace(); } } private static boolean isCommandAvailable(String command) { try { if (PlatformUtils.getOperatingSystem() == PlatformUtils.OS.WINDOWS) { CommandResult result = CommandExecutor.execute("where " + command.split(" ")[0]); return result.isSuccess(); } else { CommandResult result = CommandExecutor.execute("which " + command.split(" ")[0]); return result.isSuccess(); } } catch (Exception e) { return false; } } /** * 获取详细错误信息 */ public static String getDetailedErrorInfo(Process process) { StringBuilder errorInfo = new StringBuilder(); try (BufferedReader errorReader = new BufferedReader( new InputStreamReader(process.getErrorStream()))) { String line; while ((line = errorReader.readLine()) != null) { errorInfo.append(line).append("\n"); } } catch (IOException e) { errorInfo.append("Failed to read error stream: ").append(e.getMessage()); } return errorInfo.toString(); } }总结
本文详细介绍了Java执行操作系统命令的各个方面,涵盖了从基础API使用到高级应用的完整知识体系。主要内容包括:
核心API:Runtime.exec()和ProcessBuilder的详细用法
跨平台解决方案:如何编写在不同操作系统上都能工作的代码
常用命令分类实现:文件系统、系统信息、进程管理、网络命令
高级特性:流式处理、超时控制、安全实践
实战应用:系统监控工具、批量命令执行器
问题诊断:常见问题解决和调试技巧
关键要点:
优先使用ProcessBuilder:它比Runtime.exec()更安全、更灵活
始终处理输出流:避免进程阻塞
实现超时控制:防止长时间运行的命令
验证用户输入:防止命令注入攻击
使用合适的线程模型:对于长时间运行或需要实时输出的命令
性能建议:
对于批量命令执行,使用线程池提高效率
缓存频繁使用的命令结果
使用异步执行避免阻塞主线程
合理设置缓冲区大小,避免内存问题
通过掌握这些技术,您可以构建强大、可靠、安全的系统管理和自动化工具,充分利用操作系统功能的同时保持Java应用的可移植性和健壮性。