java Runtime.exec(字符串[])是否独立于平台?

java Runtime.exec(字符串[])是否独立于平台?,java,process,command-execution,Java,Process,Command Execution,我有一些通过Runtime.getRuntime.exec(String)运行命令的代码,它可以在Windows上运行。当我将代码移到Linux时,它坏了,唯一的修复方法是切换到exec(String[])版本。如果我不这样做,那么代码在Windows和Linux上的工作方式是相同的,还是应该在Windows上使用exec(字符串),在Linux上使用exec(字符串[]) 此方法检查cmdarray是否为 有效的操作系统命令。哪个 命令是有效的 依赖于系统,但最重要的是 至少该命令必须是非空的

我有一些通过Runtime.getRuntime.exec(String)运行命令的代码,它可以在Windows上运行。当我将代码移到Linux时,它坏了,唯一的修复方法是切换到exec(String[])版本。如果我不这样做,那么代码在Windows和Linux上的工作方式是相同的,还是应该在Windows上使用exec(字符串),在Linux上使用exec(字符串[])

此方法检查cmdarray是否为 有效的操作系统命令。哪个 命令是有效的 依赖于系统,但最重要的是 至少该命令必须是非空的 非空字符串的列表

因此,是的,它依赖于系统。 顺便说一句,你可以发布相关代码,这样我们就可以看到你(最终)做错了什么


[1] :,java.lang.String[],java.io.File)

好的,我放弃了:您可以向exec()传递什么非平凡的命令,并期望在Windows和Linux上都得到合理的结果?询问exec()是否与平台无关似乎忽略了exec()的全部要点,即调用特定于平台的行为


要真正回答您的问题,请回答“是”-在不同的平台上解释命令字符串的方式会有所不同(对于不同的shell,在Linux上可能会有所不同),使用string[]版本更有可能最终正确传递参数。

用于拆分exec(字符串)的默认标记器参数转换为字符串[]只需按空格字符将其拆分。它不像手动输入的shell命令那样解释引号,因此应该调用字符串[]版本。但是,如果您在两个平台上都使用sunjdk,那么行为应该是相似的

但是,由于Windows提供了与其他操作系统不同的shell命令(例如复制而不是cp),因此您的命令可能无法在所有平台上运行。

exec()调用底层操作系统上的本机命令


为Windows设计的命令在Linux上不起作用,必须重写。

在这两种系统上都使用String[]

我的答案是,调试一个运行在windows上的生产软件几个小时的痛苦结果

经过大量的努力,我们(我)找到了之前发布的解决方案(使用String[]

由于您遇到的问题是在Linux上,我想在两者上使用阵列将是最好的

顺便说一句,我在Java1.4中尝试了这种方法,从那时起,一个新的类就可用了:添加到Java1.5中。我不确定这到底是怎么回事,但这应该有一个很好的理由。看一看,并了解Runtime.exec与Runtime.exec的区别。也许这将是一个更好的选择

最后,有些命令在这两种平台上都不起作用,因为它们是与shell(Windows cmd或bash/sh/etc)一起内置的,例如dir或echo等。因此,我建议在每个目标平台上进行额外/额外测试,并为不受支持的命令添加异常处理程序


:)

采用单个字符串的exec()方法与接受数组的方法之间的区别在于,数组版本允许您指定如何分解命令及其参数(即正确地分解)。 当您使用只接受字符串的方法时,该方法会将其拆分为一个空格数组。从那时起,两种方法的处理方式相同

这是运行时类中的代码,它显示了如何将单个字符串拆分为数组,然后调用string[]version以继续处理

   public Process exec(String command, String[] envp, File dir)
            throws IOException {
         if (command.length() == 0)
             throw new IllegalArgumentException("Empty command");

         StringTokenizer st = new StringTokenizer(command);
         String[] cmdarray = new String[st.countTokens()];
         for (int i = 0; st.hasMoreTokens(); i++)
             cmdarray[i] = st.nextToken();
         return exec(cmdarray, envp, dir);
     }

因此,如果在whitspace上中断命令不能正确地分离命令和参数,则接受字符串的方法将不起作用。

如果要在Windows和Linux上运行不同的命令,可以使用以下类似的方法找出正在运行的操作系统:

        String os = System.getProperty("os.name").toLowerCase();
        if (os.indexOf("win") >= 0) {
            // Windows Commands
        } else {
            // Linux Commands
        }

另一个好方法是在脚本(.bat用于Windows,.sh用于Linux)中编写您的命令,并调用这些脚本。

Nice,在预览中,链接不会断开!我试图为项目中的所有.java文件执行javac,并包括jar依赖项。啊,我应该猜到-从java应用程序中运行JDK命令是一件合理的事情。@Mark。实际上没有那么多。双方的论点是不同的,比如path/和path separator:vs;驱动器等。因此命令不会真正从一个平台透明地运行到另一个平台。@Geo:从java 1.6开始,我认为java编译器有一个API。我认为类似于java.lang.Compiler,添加它正是为了避免此类问题,并允许Servlet容器等容器从应用程序内部而不是通过外部进程编译生成的.java文件。