java Runtime.exec(String[]) 平台独立吗?

发布于 2024-07-26 06:56:48 字数 241 浏览 4 评论 0原文

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

I had some code that ran commands through Runtime.getRuntime.exec(String), and it worked on Windows. When I moved the code to Linux, it broke, and the only way of fixing it was to switch to the exec(String[]) version. If I leave things this way, will the code work the same on Windows and Linux, or should I use the exec(String) on Windows and exec(String[]) on Linux?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

月寒剑心 2024-08-02 06:56:48

两者都使用String[]

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

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

因为您遇到的问题是在 Linux 上,我想在两者上使用数组将是最好的。

顺便提一句。 我用 Java 1.4 尝试了该方法,从那时起,一个新类可用: ProcessBuilder 添加于 Java1.5。 我不确定这到底是怎么回事,但应该有一个充分的理由。 看一下它并了解 Runtime.exec 之间的区别。 也许这将是一个更好的选择。

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

:)

Use String[] on both.

The answer I gave you before was the result of several miserable hours of debugging a production software running on windows.

After a lot of effort we ( I ) came to the solution posted before ( use String[] )

Since the problems you've got were on Linux, I guess using the array on both will be the best.

BTW. I tried that method with Java 1.4, Since then a new class is available: ProcessBuilder added on Java1.5. I'm not sure what is that all about, but there should be a good reason for it. Take a look at it and read what the difference between that an Runtime.exec is. Probably it will be a better option.

Finally some commands won't work on either platform because they are built in with the shell ( either Windows cmd or bash/sh/ etc ) such as dir or echo and some of those. So I would recommend do extra/extra test on each target platform and add exception handlers for the unsupported commands.

:)

呆萌少年 2024-08-02 06:56:48

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

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

Okay, I give up: What non-trivial command can you pass to exec(), and expect to get reasonable results on both Windows and Linux? Asking whether exec() is platform independent kind of seems to be missing the whole point of exec(), which is to invoke platform-specific behavior.

To actually address your question, yes - the way that the command string is interpreted will be different on different platforms (and potentially, for different shells, on Linux), and using the String[] version is more likely to end up with the parameters getting passed correctly.

-黛色若梦 2024-08-02 06:56:48

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

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

The default Tokeniser for splitting the exec(String) parameter into a String[] simply splits them by the space character. It does not interpret quotes like a manually entered shell command would, so you should call the String[] version. But if you are using the Sun JDK on both platforms, the behaviour should be similar.

However, as Windows provides different shell commands as other Operating Systems (for example copy instead of cp), your commands might not work on all platforms.

揽清风入怀 2024-08-02 06:56:48

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

这是 Runtime 类中的代码,显示了如何将单个字符串分解为数组,然后调用 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);
     }

因此,如果在空白处中断命令无法正确分隔命令和参数,则接受字符串的方法将不起作用。

The difference between the the exec() method that takes a single string, and the one that accepts an array is that the array version allows you to specify how the command and its arguments need to be broken up (ie. correctly).
When you use the method(s) that accept just a string the method breaks it up into an array on whitespace. Processing from then on is handled the same for both methods.

This is the code from Runtime class that shows how it breaks single string into an array and then calls String[] version to continue processing.

   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);
     }

So the method that accepts a String will not work if breaking the command on whitspace does not separate command and arguments correctly.

萝莉病 2024-08-02 06:56:48

来自 [API][1]

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

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

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

From [the api][1]

This method checks that cmdarray is a
valid operating system command. Which
commands are valid is
system-dependent, but at the very
least the command must be a non-empty
list of non-null strings.

So yes, it is system-dependent.
BTW, could you post the relevant code, so we can see what you're (eventually) do wrong?

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

涙—继续流 2024-08-02 06:56:48

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

为 Windows 设计的命令不适用于 Linux,必须重写。

exec() invokes native commands on the underlying operating system.

Commands designed for Windows will not work on Linux, and will have to be rewritten.

东北女汉子 2024-08-02 06:56:48

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

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

另一个好处是将您的命令写入脚本中(对于 Windows 为 .bat,对于 Linux 为 .sh) )并调用这些脚本。

If you want to run different commands on Windows and Linux you could find out which OS is running by using something like the following:

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

Another good thing would be to write you're commands in a script (.bat for Windows and .sh for Linux) and call these scripts instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文