如何使用包含双引号的参数从Java启动进程

时间:2013-08-07 09:20:49

标签: java command-line process command-line-arguments

我需要从我的Java程序启动第二个Java进程,并且分叉进程的一个参数需要包含文字双引号字符(")。我如何以便携方式实现这一点,即至少它可以在Linux和Windows上运行?


我尝试使用ProcessBuilder(为了克服Runtime类的问题而引入,对吧?),并将一个字符串数组作为命令行,但参数仍有问题包含引用:

List<String> commandLine = new ArrayList<String>();
commandLine.add(new File(System.getProperty("java.home") + "/bin/java").getAbsolutePath());
commandLine.addAll(Arrays.asList("-jar", "plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar", "-application", "org.eclipse.equinox.p2.director", "-repository", "http://download.eclipse.org/releases/juno"));
commandLine.add("-list");
commandLine.add("Q:select(x | x.id == \"org.eclipse.sdk.ide\")");

new ProcessBuilder().command(commandLine).directory(eclipseInstallationDir).start().waitFor();

上面的代码不起作用(在Windows上),因为ProcessBuilder(或其他东西)会在最后一个参数中占用双引号:

进程接收参数Q:select(x | x.id == "org.eclipse.sdk.ide")而不是Q:select(x | x.id == org.eclipse.sdk.ide),而不是\"


我发现我可以通过在我需要"的参数中添加commandLine.add("Q:select(x | x.id == \"org.eclipse.sdk.ide\")".replace("\"", "\\\"")); 来使其在Windows上运行,即

{{1}}

但这打破了Linux上的调用(正如morgano所证实的那样)。所以我不得不再次检测操作系统。是否真的没有简单,可移植的方式来启动Java中的进程,其中参数正是字符串数组的内容?

1 个答案:

答案 0 :(得分:1)

通常,命令参数字符串围绕空格分割以形成参数数组。但是,如果您希望单个参数包含空格,则可以将参数包装在引号中。之后,每个的引号都将从字符串中删除。删除这些引号并不是java - 操作系统本身就是这样做的。

ProcessBuilder将您提供的每个参数包装在引号中,这样如果任何参数包含空格,操作系统将不会将其拆分为多个参数(您可以通过提供{{ 1}};这将最终成为两个参数:1234\" \"56781234)。然后,ProcessBuilder将所有参数连接成一个命令,并将其传递给操作系统。稍后,操作系统按空格和引号(如上所述)拆分命令字符串,然后在开始新进程之前从每个字符串参数中删除所有引号对。要转义引号(即将其视为OS解析器未处理的常规字符),请在其前面使用反斜杠字符。这是Linux和Windows的命令行转义字符。这看起来像是:5678