方法1:使用 Runtime.exec()
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class AixCommandExecutor {
public static void main(String[] args) {
try {
// 1. 定义AIX命令
String command = "oslevel -s"; // 示例:获取AIX系统版本
// 2. 执行命令
Process process = Runtime.getRuntime().exec(command);
// 3. 读取标准输出
BufferedReader outputReader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
// 4. 读取错误流(避免阻塞)
BufferedReader errorReader = new BufferedReader(
new InputStreamReader(process.getErrorStream())
);
// 5. 获取命令输出
StringBuilder result = new StringBuilder();
String line;
while ((line = outputReader.readLine()) != null) {
result.append(line).append("\n");
}
// 6. 获取错误信息
StringBuilder error = new StringBuilder();
while ((line = errorReader.readLine()) != null) {
error.append(line).append("\n");
}
// 7. 等待命令执行完成
int exitCode = process.waitFor();
// 8. 处理结果
if (exitCode == 0) {
System.out.println("命令执行成功:\n" + result);
} else {
System.out.println("命令执行失败(错误码 " + exitCode + "):\n" + error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
方法2:使用 ProcessBuilder(推荐)
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class AixCommandExecutor {
public static void main(String[] args) {
// 1. 定义命令(支持参数)
ProcessBuilder processBuilder = new ProcessBuilder("ls", "-l", "/tmp");
try {
// 2. 启动进程
Process process = processBuilder.start();
// 3. 读取输出和错误流
try (BufferedReader outputReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(
new InputStreamReader(process.getErrorStream()))) {
// 4. 获取输出内容
StringBuilder result = new StringBuilder();
String line;
while ((line = outputReader.readLine()) != null) {
result.append(line).append("\n");
}
// 5. 获取错误内容
StringBuilder error = new StringBuilder();
while ((line = errorReader.readLine()) != null) {
error.append(line).append("\n");
}
// 6. 等待命令结束
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("输出结果:\n" + result);
} else {
System.out.println("错误信息:\n" + error);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
关键注意事项
-
流读取顺序
必须同时读取标准输出流和错误流,否则缓冲区满会导致进程阻塞,建议使用多线程或CompletableFuture并行读取(参考)。 -
命令路径问题
AIX系统命令通常位于/usr/bin等目录,建议使用绝对路径(如/usr/bin/oslevel)或确保环境变量PATH已配置。 -
权限处理
若需执行特权命令(如lparstat),需确保Java进程有足够权限(通过sudo或配置用户角色)。 -
超时控制
长时间未响应的命令需添加超时机制:if (!process.waitFor(30, TimeUnit.SECONDS)) { // 30秒超时 process.destroy(); throw new RuntimeException("命令执行超时"); } -
字符编码
若输出含非英文字符,需指定编码(如new InputStreamReader(process.getInputStream(), "IBM-850"))。
常见问题解决
- 错误流未读取导致卡死:始终启动独立线程读取错误流。
- 命令存在但执行失败:检查用户权限和环境变量(如
PATH)。 - 截断:确保完整读取流内容(循环直到
readLine()返回null)。
最佳实践
- 使用
ProcessBuilder替代Runtime.exec()(更灵活的参数管理)。 - 封装工具类复用流读取逻辑。
- 敏感命令避免硬编码(从配置读取)。
引用说明:本文代码基于Oracle官方文档ProcessBuilder和IBM AIX命令手册实现,遵循Java跨平台规范,安全建议参考OWASP命令注入防护。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/7682.html