【问题标题】:Execute process from Java irrespective of underlying OS无论底层操作系统如何,都从 Java 执行进程
【发布时间】:2013-09-06 10:24:06
【问题描述】:

你能告诉我一种不管底层操作系统如何从 Java 执行进程的方法吗?例如。

Process p = Runtime.getRuntime().exec("cmd /c mvn clean install");

以上行在 Windows 环境中执行 Maven,但我如何在任何操作系统中运行以上命令?

如果我没有在启动时添加"cmd/c",那么我将无法在windows环境中运行,并且错误提示cannot find mvn.bat虽然maven home设置正确。

【问题讨论】:

    标签: java process runtime.exec


    【解决方案1】:

    您可以检查您拥有的操作系​​统类型,然后执行命令行语句。

    为了检查操作系统类型,您需要检索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);
    }
    

    更多信息您可以找到here

    【讨论】:

      【解决方案2】:

      你真的不能从字面上“从 Java 执行进程而不管底层操作系统”,因为Runtime.exec 在操作系统顶部转发一个启动命令。然后,您必须描述要启动的过程以及执行此操作的方法。 但是,您可以通过为您知道的进程实现一个ProcessLauncher 接口以及为每个操作系统的子类启动来“虚拟化”进程启动 使用工厂检测您在哪个操作系统上并创建正确的 ProcessLauncher,您应该没问题

      【讨论】:

        【解决方案3】:

        您可能必须检查它是哪个操作系统,然后将cmd /c 替换为该操作系统的相关命令。

        请参阅此问题以了解如何确定您在哪个系统上运行:How do I programmatically determine operating system in Java?

        【讨论】:

          【解决方案4】:

          执行外部程序根据定义与平台无关。程序可能安装在不同的地方,PATH 的设置不同或调用语法不同。 (例如,Windows 上的 /all 和 unix 上的 --all)。 (更不用说可能有来自不同人的不同程序来完成相同的任务。)

          最好的办法是为您的程序使用配置文件,您可以在其中指定什么程序以及如何调用它,或者以特定于平台的方式设置程序执行环境(例如使用 start .bat / start.sh) 并使用System.getEnv()

          我个人最喜欢第一种方法,因为它不会产生副作用。另一方面,第二个允许“系统黑客”将一些代码放在那里做......嗯......他们的东西(例如,参见Tomcat的startup.sh/bat catalina.sh/bat):)

          【讨论】:

            【解决方案5】:

            对于这种特殊情况,有一些库可以提供帮助,例如,您可以以编程方式使用 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 任务将下载它需要的任何其他内容第一次运行。

            【讨论】:

              【解决方案6】:

              最好使用 apache commons exec 来运行外部程序,因为存在许多特定于操作系统平台的问题,例如输出流缓冲区大小、错误处理等。

              【讨论】:

                猜你喜欢
                • 2010-10-17
                • 1970-01-01
                • 1970-01-01
                • 2015-02-24
                • 2012-06-09
                • 2014-10-17
                • 1970-01-01
                • 2012-07-14
                • 1970-01-01
                相关资源
                最近更新 更多