你能告诉我一种不管底层操作系统如何从 Java 执行进程的方法吗?例如
Process p = Runtime.getRuntime().exec("cmd /c mvn clean install");
上面的行在 Windows 环境中执行 Maven,但是如何在任何操作系统中运行上面的命令?
如果我不添加"cmd/c"
启动,那么我将无法在 Windows 环境中运行,并且错误提示cannot find mvn.bat
虽然 maven home 设置正确。
你能告诉我一种不管底层操作系统如何从 Java 执行进程的方法吗?例如
Process p = Runtime.getRuntime().exec("cmd /c mvn clean install");
上面的行在 Windows 环境中执行 Maven,但是如何在任何操作系统中运行上面的命令?
如果我不添加"cmd/c"
启动,那么我将无法在 Windows 环境中运行,并且错误提示cannot find mvn.bat
虽然 maven home 设置正确。
您可以检查您拥有的操作系统类型,然后执行命令行语句。
为了检查操作系统类型,您需要检索os.name
系统属性的值:
String OS = System.getProperty("os.name").toLowerCase();
然后使用一个简单的if/else
语句,您可以根据操作系统的类型执行命令行语句。
if (isUnix()) {
String statement = new String[] { "/bin/bash", "-c", "mvn clean install" };
Process p = Runtime.getRuntime().exec(statement);
else if (isWindows()) {
Process p = Runtime.getRuntime().exec("cmd /c mvn clean install");
}
...
检查操作系统类型的辅助方法:
public boolean isUnix() {
return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0 );
}
public boolean isWindows() {
return (OS.indexOf("win") >= 0);
}
您可以在此处找到更多信息。
您真的不能从字面上“从 Java 执行进程而不管底层操作系统如何”,因为Runtime.exec
在操作系统顶部转发启动命令。然后,您必须描述要启动的过程以及执行此操作的方法。但是,您可以通过为您知道的进程实现一个接口来“虚拟化”进程启动,ProcessLauncher
并为每个操作系统的子类启动使用一个工厂来检测您在哪个操作系统上,并创建正确的 ProcessLauncher,您应该没问题
更好地使用 apache commons exec 来运行外部程序,因为存在许多操作系统平台特定的问题,例如输出流缓冲区大小、错误处理等。
您可能必须检查它是哪个操作系统,然后cmd /c
用该操作系统的相关命令替换。
有关如何确定您正在运行的系统,请参阅此问题:如何以编程方式确定 Java 中的操作系统?
执行外部程序是根据定义与平台无关的。程序的安装位置可能不同,PATH 设置不同或调用语法不同。(例如/all
在 Windows 和--all
unix 上)。(更不用说可能有来自不同人的不同程序来完成相同的任务。)
您最好的选择是使用您的程序的配置文件,您可以在其中指定什么程序以及如何调用它,或者以特定于平台的方式设置程序执行环境(例如使用 start.bat / start.sh) 并使用System.getEnv()
.
我个人最喜欢的是第一种方法,因为它没有处理副作用。另一方面,第二个允许“系统黑客”将一些代码放在那里做......嗯......他们的东西(例如,参见Tomcat的startup.sh/bat catalina.sh/bat):)
对于这种特殊情况,有一些库可以提供帮助,例如,您可以以编程方式使用maven-ant-tasks库,因为 Ant 将所有特定于平台的混乱隐藏在其自己的平台无关 API 后面:
Project p = new Project();
p.init();
Mvn mvnTask = new Mvn();
mvnTask.setProject(p);
mvnTask.setPom(new File("path/to/pom.xml"));
mvnTask.createArg().setValue("clean");
mvnTask.createArg().setValue("install");
mvnTask.perform();
这应该在所有平台上都一样,并且不需要独立安装mvn
- 您只需要在类路径上安装 Ant 和maven-ant-tasks
库,并且该Mvn
任务将在第一次运行时下载它需要的任何其他内容。