Java创建子进程(Process)执行外部命令底层的方法是new ProcessBuilder().start()或Runtime.getRuntime().exec()。
Apache commons-exec对底层进行封装,提供了更加详细的设置和监控方法。
pom.xml
1 2 3 4 5
   | <dependency> 	<groupId>org.apache.commons</groupId> 	<artifactId>commons-exec</artifactId> 	<version>1.3</version> </dependency>
   | 
 
CmdHelper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
   | import java.io.IOException; import java.io.OutputStream; import java.util.concurrent.CompletableFuture;
  import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.exec.ShutdownHookProcessDestroyer;
  public class CmdHelper { 	
 
 
 
 
 
 
  	public static CmdHandler run(CommandLine commandLine, OutputStream out, long timeout) { 		PumpStreamHandler pumpStreamHandler = null; 		if (null == out) { 			pumpStreamHandler = new PumpStreamHandler(); 		} else { 			pumpStreamHandler = new PumpStreamHandler(out); 		}
  		DefaultExecutor executor = new DefaultExecutor(); 		CmdHandler cmdHandler = new CmdHandler(executor); 		executor.setStreamHandler(pumpStreamHandler); 		ShutdownHookProcessDestroyer processDestroyer = new ShutdownHookProcessDestroyer(); 		executor.setProcessDestroyer(processDestroyer);
  		if (timeout <= 0) { 			timeout = ExecuteWatchdog.INFINITE_TIMEOUT; 		} 		ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout); 		executor.setWatchdog(watchdog);
  		try { 			executor.execute(commandLine, cmdHandler); 			cmdHandler.waitFor(); 		} catch (IOException | InterruptedException e) { 			e.printStackTrace(); 		} 		return cmdHandler; 	}
  	
 
 
 
 
 
 
  	public static CompletableFuture<CmdHandler> exec(CommandLine commandLine, OutputStream out, long timeout) { 		CompletableFuture<CmdHandler> cf = new CompletableFuture<>(); 		PumpStreamHandler pumpStreamHandler = null; 		if (null == out) { 			pumpStreamHandler = new PumpStreamHandler(); 		} else { 			pumpStreamHandler = new PumpStreamHandler(out); 		}
  		DefaultExecutor executor = new DefaultExecutor(); 		CmdHandler cmdHandler = new CmdHandler(executor); 		cmdHandler.setCallback(() -> { 			cf.complete(cmdHandler); 		}); 		executor.setStreamHandler(pumpStreamHandler); 		ShutdownHookProcessDestroyer processDestroyer = new ShutdownHookProcessDestroyer(); 		executor.setProcessDestroyer(processDestroyer);
  		if (timeout <= 0) { 			timeout = ExecuteWatchdog.INFINITE_TIMEOUT; 		} 		ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout); 		executor.setWatchdog(watchdog);
  		try { 			executor.execute(commandLine, cmdHandler); 		} catch (IOException e) { 			e.printStackTrace(); 		} 		return cf; 	}
  	public static void main(String[] args) throws InterruptedException { 		CommandLine command = CommandLine.parse("ping 127.0.0.1 -t");
  		 		CmdHandler result = CmdHelper.run(command, null, 3000); 		System.out.println(result.resultString());
  		 		CmdHelper.exec(command, null, 0).thenAccept(cmdHandler -> {     		System.out.println(cmdHandler.resultString()); 		}); 	} }
   | 
 
CmdHandler.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
   | import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.ExecuteException; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.Executor;
  public class CmdHandler extends DefaultExecuteResultHandler { 	Executor executor; 	Runnable callback; 	 	public CmdHandler(Executor executor) { 		this.executor = executor; 	} 	 	public void setCallback(Runnable callback) { 		this.callback = callback; 	} 	 	public Executor getExecutor() { 		return this.executor; 	} 	 	public ExecuteWatchdog getWatchdog() { 		if (this.executor == null) return null; 		return this.executor.getWatchdog(); 	} 	 	public String resultString() { 		String retMsg = "complete"; 		if (this.getException() != null) { 			ExecuteWatchdog watchdog = this.getWatchdog(); 			if (watchdog != null && watchdog.killedProcess()) { 				retMsg = "timeout"; 			} else { 				retMsg = this.getException().getMessage(); 			} 		} 		return this.getExitValue() + ":" + retMsg; 	}
  	@Override 	public void onProcessComplete(int exitValue) { 		super.onProcessComplete(exitValue); 		if (callback != null) { 			callback.run(); 		} 	}
  	@Override 	public void onProcessFailed(ExecuteException e) { 		super.onProcessFailed(e); 		if (callback != null) { 			callback.run(); 		} 	} }
   | 
 
参考
- https://www.cnblogs.com/kingcucumber/p/3180146.html
 
- https://www.jianshu.com/p/73aaec23009d