在Java中使用Apache Commons Exec库执行多条命令,可以通过以下几种方式实现
方法1:使用命令连接符(推荐)
通过&&(Windows/Linux均支持)或;(Linux)连接多条命令,一次性执行:
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import java.io.ByteArrayOutputStream;
public class ExecMultipleCommands {
    public static void main(String[] args) throws Exception {
        // 组合命令(Windows示例)
        CommandLine cmd = new CommandLine("cmd.exe");
        cmd.addArgument("/c");  // 执行后关闭
        cmd.addArgument("echo First Command && mkdir test_dir && echo Done", false); // false: 禁止解析参数
        
        // Linux/macOS示例
        // CommandLine cmd = new CommandLine("/bin/sh");
        // cmd.addArgument("-c");
        // cmd.addArgument("echo 'First Command'; mkdir test_dir; echo 'Done'", false);
        // 捕获输出
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        PumpStreamHandler streamHandler = new PumpStreamHandler(output);
        DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(streamHandler);
        
        int exitCode = executor.execute(cmd);
        System.out.println("Exit Code: " + exitCode);
        System.out.println("Output:\n" + output.toString());
    }
}
方法2:循环执行多条命令
单独执行每条命令,适合需要独立处理结果的场景:
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
public class ExecLoopCommands {
    public static void main(String[] args) throws Exception {
        String[] commands = {
            "echo First Command",  // Windows/Linux通用
            "mkdir test_dir_loop", // 创建目录
            "echo Done"
        };
        for (String command : commands) {
            CommandLine cmd;
            if (System.getProperty("os.name").startsWith("Windows")) {
                cmd = new CommandLine("cmd.exe");
                cmd.addArgument("/c");
                cmd.addArgument(command, false);
            } else {
                cmd = new CommandLine("/bin/sh");
                cmd.addArgument("-c");
                cmd.addArgument(command, false);
            }
            
            int exitCode = new DefaultExecutor().execute(cmd);
            System.out.println("Command: " + command + " | Exit Code: " + exitCode);
        }
    }
}
关键注意事项:
- 
	
操作系统兼容性:
- 
		
Windows:使用
cmd.exe /c "命令" - 
		
Linux/macOS:使用
/bin/sh -c "命令" 
 - 
		
 - 
	
特殊字符处理:
- 
		
使用
addArgument(..., false)避免解析参数中的特殊字符 - 
		
复杂命令建议用双引号包裹:
cmd.addArgument("\"your command\"", false) 
 - 
		
 - 
	
错误处理:
- 
		
try { executor.execute(cmd); } catch (ExecuteException e) { System.err.println("Execution failed: " + e.getMessage()); System.err.println("Exit code: " + e.getExitValue()); } 
 - 
		
 - 超时控制:
	
- 
		
ExecuteWatchdog watchdog = new ExecuteWatchdog(5000); // 5秒超时 executor.setWatchdog(watchdog);
 
 - 
		
 - 
	
输出重定向:
- 
		
使用
PumpStreamHandler捕获输出 - 
		
用
System.out直接打印:executor.setStreamHandler(new PumpStreamHandler(System.out)) 
 - 
		
 
最佳实践:
- 
	
简单命令序列 → 使用
&&连接(方法1) - 
	
需要独立错误处理 → 循环执行(方法2)
 - 
	
复杂脚本 → 保存为脚本文件并执行
 - 
	
跨平台 → 根据
os.name动态选择命令前缀 
常见问题解决:
问题1:命令在命令行能运行,但Java中失败
解决:显式指定shell路径(如Windows用C:\\Windows\\System32\\cmd.exe)
问题2:空格/引号解析错误
解决:使用addArgument单独添加参数,避免拼接字符串:
cmd.addArgument("/c");
cmd.addArgument("echo", false);
cmd.addArgument("Hello World", false);  // 作为独立参数传递
通过以上方法,你可以灵活地在Java中使用Commons Exec执行多条命令,并根据需求选择最适合的实现方式。