【问题标题】:Execute with parameters带参数执行
【发布时间】:2010-01-27 02:20:09
【问题描述】:

我在 Java 中执行需要参数的批处理文件时遇到困难。这些参数可能包含空格,因此我需要将它们用引号引起来。我还需要为 Linux 做同样的事情,因为某些参数可能包含特殊字符,例如 !

非功能性 Windows 代码:

ProcessBuilder pb = new ProcessBuilder(
        "cmd",
        "/c",
        "\"mybat.bat\"",
        "\"param 1\"",
        "\"param 2\"",
        "\"param 3\""
        );    

非功能性 Linux 代码:

ProcessBuilder pb = new ProcessBuilder(
        "bash",
        "-c",
        "'myshellscript.sh'",
        "'param 1'",
        "'param 2'",
        "'param 3'"
        ); 

我知道我应该像下面的 Windows 示例一样添加参数,但这不适用于空格:

ProcessBuilder pb = new ProcessBuilder(
        "cmd",
        "/c",
        "mybat.bat param 1 param 2 param 3"
        );   

这应该怎么做?

【问题讨论】:

  • 您没有将它们用引号引起来吗?你为什么不为你最后的 sn-p 做呢?
  • 我正在尝试使前两个 sn-ps 工作。第三个sn -p 在我只找三个的时候会传6个参数给mybat.bat。

标签: java batch-file


【解决方案1】:

Windows:

ProcessBuilder pb = new ProcessBuilder(
        "cmd", "/c", "mybat.bat", 
        "param 1", "param 2", "param 3");

Unix:

ProcessBuilder pb = new ProcessBuilder(
        "sh", "mybat.sh", 
        "param 1", "param 2", "param 3");

【讨论】:

  • 为什么会这样? java.io.IOException: java.io.IOException: sh: 在 java.lang.ProcessImpl.start(ProcessImpl.java:65) 在 java.lang.UNIXProcess.(UNIXProcess.java:148) 在 java 中找不到.lang.ProcessBuilder.start(ProcessBuilder.java:451) 在 DmMdbConsumer.migrateData(DmMdbConsumer.java:328) 在 DmMdbConsumer.run(DmMdbConsumer.java:230) 在 java.lang.Thread.run(Thread.java:595)
  • "sh" 在我的情况下必须是 "/bin/sh"。谢谢!
  • 您可能无法访问 korn shell。根据您有权访问的外壳程序,使用该外壳程序(bash、csh、rsh)或者您可以使您的脚本可执行并完全删除“sh”参数。
  • "/bin" 应该已经在您的 PATH 中。但如果不是,并且你对“/bin/sh”有执行权限,你也可以使用它。
  • 似乎没有任何东西在 linux 的路径上。我的第一次尝试是执行 java -jar 而不是 mybat.bat 或 myshell.sh。 Windows 运行良好,但在 Linux 中没有运气。我能够在 Linux 中打开一个终端窗口并输入 java --version 并获得一个版本。
【解决方案2】:

不,您应该引用 *nix 上的参数。在交互式 shell 中的 *nix 上引用是必要的,以防止 shell 误解它们,但是当直接启动进程时,不涉及 shell。因此无需引用。

如果您确实包含引号,启动的进程会将它们视为其传入参数的一部分并执行诸如(例如)尝试打开包含引号的文件名之类的事情。

您也不希望 bash 使用“-c”参数。这告诉它将下一个参数解析为命令行,但您提供的是参数列表。删除“-c”选项和多余的引号,它应该可以工作。

正确的 Linux 调用应该是:

ProcessBuilder pb = new ProcessBuilder(
    "bash",
    "myshellscript.sh",
    "param 1",
    "param 2",
    "param 3"
    );

如果文件“myshellscript.sh”是可执行的并且有适当的shebang行(例如“#!/bin/bash”),你也不需要“bash”参数。这是可取的,因为如果脚本被替换为用不同语言编写的脚本,您将不必更新您的调用应用程序。

同样,在 Windows 上,您不需要“cmd”和“/c”参数。进程启动器/操作系统应自动处理启动批处理文件(基于扩展名)。

【讨论】:

  • 不幸的是,我需要 Windows 的 cmd 和 /c。我的 shell 脚本确实有 shebang 行,但无论有没有 sh,我都无法让它工作。
猜你喜欢
  • 2017-01-28
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 2019-04-29
相关资源
最近更新 更多