3

我需要从我的 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)然后失败。


我发现我可以通过\"在需要"ie的参数中添加 a 来使其在 Windows 上运行

commandLine.add("Q:select(x | x.id == \"org.eclipse.sdk.ide\")".replace("\"", "\\\""));

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

4

1 回答 1

1

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

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

于 2013-08-07T10:33:46.410 回答