4

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

4

7 回答 7

5

在两者上都使用String[]

我之前给你的答案是调试在 Windows 上运行的生产软件几个小时的结果。

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

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

顺便提一句。我在 Java 1.4 中尝试了这种方法,从那时起就有了一个新类: Java1.5 上添加了ProcessBuilder。我不确定这是怎么回事,但应该有一个很好的理由。看一下它并阅读 Runtime.exec 之间的区别。可能这将是一个更好的选择。

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

:)

于 2009-07-04T00:34:03.593 回答
2

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

要真正解决您的问题,是的 - 解释命令字符串的方式在不同平台上会有所不同(并且可能对于不同的 shell,在 Linux 上),并且使用 String[] 版本更有可能以参数结束正确通过。

于 2009-07-03T23:05:17.203 回答
2

将 exec(String) 参数拆分为 String[] 的默认 Tokeniser 只是通过空格字符将它们拆分。它不会像手动输入的 shell 命令那样解释引号,因此您应该调用 String[] 版本。但如果您在两个平台上都使用 Sun JDK,则行为应该相似。

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

于 2009-07-03T23:14:26.157 回答
2

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

这是来自 Runtime 类的代码,它显示了它如何将单个字符串分解为一个数组,然后调用 String[] 版本继续处理。

   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 上破坏命令没有正确分隔命令和参数,则接受字符串的方法将不起作用。

于 2009-07-04T00:57:12.797 回答
1

来自[api][1]

此方法检查 cmdarray 是否为有效的操作系统命令。哪些命令有效取决于系统,但至少该命令必须是非空字符串的非空列表。

所以是的,它依赖于系统。顺便说一句,您能否发布相关代码,以便我们可以看到您(最终)做错了什么?

[1]: http: //java.sun.com/javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String[] , java.lang.String[], java.lang. io.文件)

于 2009-07-03T23:03:58.487 回答
1

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

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

于 2009-07-04T00:18:30.567 回答
1

如果您想在 Windows 和 Linux 上运行不同的命令,您可以使用以下内容找出正在运行的操作系统:

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

另一件好事是在脚本中编写命令(Windows 为 .bat,Linux 为 .sh),然后调用这些脚本。

于 2009-07-04T01:24:50.247 回答