【问题标题】:Execute command from java which might include spaces从可能包含空格的java执行命令
【发布时间】:2015-10-11 05:57:41
【问题描述】:

我正在尝试从 java 程序执行以下命令: java -jar /opt/plasma/fr.inria.plasmalab.plasmalab-1.3.4.jar -t -a montecarlo -A"Total samples"=1000 -m models/translated/plasma/NaCl2.rml:rml --format csv -r models/translated/plasma/NaCl2.bltl:bltl

使用以下代码:

String totalSample  = "-A\"Total samples\"=1000";
String mcCommand = "java -jar " + MChecker.getAppPath() + " -t "
                + "-a " + "montecarlo " + totalSample
                + " -m " + mcModelRelPath + ":rml " + "--format " + "csv "
                + "-r " + customQueryRelPath + ":bltl";

Process process = Runtime.getRuntime().exec(mcCommand);
        int errCode = process.waitFor();
        //then get the output, and error

但它会导致以下错误: 参数描述错误:动态参数需要 a=b 形式的值,但得到:"Total

我在终端中运行了相同的命令,它没有任何问题。但是当我在 Java 中创建命令并尝试调用该工具时它不起作用。

我认为这是因为 totalSample 参数包含空格而感到困惑。我接下来要做的是在参数(String totalSample = "-A\"Total\\ samples\"=1000";)中放入“\”空格转义,但它仍然拒绝接受。它给出了以下错误: 参数描述错误:动态参数需要 a=b 形式的值,但得到:"Total\

然后我使用 ProcessBuilder 对象运行相同的参数,如下所示:

 String[] mcCommand = {"java", "-jar", MChecker.getAppPath(), "-t",
         "-a", "montecarlo",totalSample, "-m",
         mcModelRelPath + ":rml", "--format", "csv", "-r",
         customQueryRelPath + ":bltl" };

ProcessBuilder pb = new ProcessBuilder(mcCommand);
Process process = pb.start();
process.waitFor();

但它仍然无法正常工作并引发了一些自定义异常。

我目前没有选择——你知道为什么这个命令不能在 Java 上工作,而它在终端界面上工作得很好?

顺便说一句:我在 Windows 上运行了相同的代码,它运行良好,但我必须在 Ubuntu OS 上运行此代码。

非常感谢

【问题讨论】:

  • 如果您认为这是空白,您是否尝试调用 trim() 来消除它并确保这不是您的问题?
  • 你能改变 jar 中的二进制文件以打印出它的参数,比如每行一个吗?或者你能写一个小罐子来做这件事并用相同的命令行调用它吗?也许这会让我们深入了解这个问题。
  • @peggy 空格字符应该在“样本总数”中,但是当它执行时,应用程序会占用 Total 部分直到空格并忽略其余部分。不知何故,我需要运行整个命令。

标签: java command-line command-line-arguments processbuilder shellexecute


【解决方案1】:

使用ProcessBuilder时不要为Total samples添加额外的引号:

ProcessBuilder pb = new ProcessBuilder("java", "-jar", MChecker.getAppPath(), "-t",
        "-a", "montecarlo", "-ATotal samples=1000",
        "-m", mcModelRelPath + ":rml", "--format", "csv",
        "-r", customQueryRelPath + ":bltl");
//...

【讨论】:

  • 你试过了吗?当您在 linux/unix 的终端中执行命令 xxx -A"y z"=1 时,shell 会删除引号,它们只是为了保留包含空格的参数,因此它将运行带有一个参数的程序 xxx-Ay z=1。它实际上相当于xxx "-Ay z=1"xxx -Ay\ z=1
  • 是的,我试过不带引号,它不起作用.. 外部工具似乎需要引号。当我通过带有引号的shell调用该工具时,该命令有效(我已在下面回答),但如果删除引号,它甚至没有额外的shell参数。但是现在,通过带引号的 shell 对我有用。谢谢。
  • 这没有意义。如果我的要求不高,您能否展示一下您在使用我的代码时遇到的错误?
【解决方案2】:

奇怪的是,Java Process 和 ProcessBuilder 类无法正确传递参数。我不知道为什么,但因为我能够从终端执行命令。我决定先调用终端,然后执行命令。因此,我将命令更改为以下

String mcCommand[] = {
            "/bin/sh",
            "-c",
            "java -jar /opt/plasma/fr.inria.plasmalab.plasmalab-1.3.4.jar -t -a montecarlo "+totalSample+" -m models/translated/plasma/NaCl2.rml:rml --format csv -r models/translated/plasma/NaCl2.bltl:bltl" };

尽管它是依赖于平台的解决方案,但目前对我来说还可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 2013-05-04
    • 2018-07-20
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多