我需要从我的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中的进程,其中参数正是字符串数组的内容?
答案 0 :(得分:1)
通常,命令参数字符串围绕空格分割以形成参数数组。但是,如果您希望单个参数包含空格,则可以将参数包装在引号中。之后,每个对的引号都将从字符串中删除。删除这些引号并不是java - 操作系统本身就是这样做的。
ProcessBuilder将您提供的每个参数包装在引号中,这样如果任何参数包含空格,操作系统将不会将其拆分为多个参数(您可以通过提供{{ 1}};这将最终成为两个参数:1234\" \"5678
和1234
)。然后,ProcessBuilder将所有参数连接成一个命令,并将其传递给操作系统。稍后,操作系统按空格和引号(如上所述)拆分命令字符串,然后在开始新进程之前从每个字符串参数中删除所有引号对。要转义引号(即将其视为OS解析器未处理的常规字符),请在其前面使用反斜杠字符。这是Linux和Windows的命令行转义字符。这看起来像是:5678
。