Java Runtime exec()无法正确转义字符

时间:2011-05-11 19:43:24

标签: java character-encoding escaping exec runtime.exec

之前可能已经回答了这个问题,但那是关于unicode的问题,我不认为这是unicode(它是ASCII格式的......)。

当我在终端中执行此操作时,没有任何问题

vboxmanage setextradata "Test Machine" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222

但是当我在Java中使用以下内容时

Runtime.getRuntime().exec("vboxmanage setextradata \"Test Machine\" \"VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort\" 2222");

它返回错误:unregistered vm'“TestMachine”'

对于像Test \ Machine这样的空格参数也是如此,那么它就不会逃避空间。

现在我认为这与字符编码有关,但我没有看到任何设置o_O的选项

4 个答案:

答案 0 :(得分:15)

你在一次调用中调用程序及其参数,这有效地将整个字符串推入处理环境(希望最好)。

在Windows系统中,操作系统以不同的方式处理可执行文件和参数,并将它们全部放在同一个字符串中只需要你选择一个完美的字符串环境(其中有两个我知道的)可以重新解析为参数列表。更好的解决方案是使用

Runtime.exec(new String[] {"vboxmanage", "setextradata", "Test Machine", "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort", "2222"});

对应Runtime's

public Process exec(String[] cmdarray)
         throws IOException

充其量,使用一个字符串方法,你最终会找到如何提示和转义参数,这样它们就不会被视为可执行文件名的一部分,但是你会遇到一个新问题,那个它们作为一个参数传递给可执行文件。一旦你根据环境修复它,你会发现你的引号没有被从参数中剥离(导致像“2222”这样的参数)或者Window的半破坏参数解析将首先解析空白(导致参数像(“测试”。这没有意义,这就是为什么有多个exec方法可用。

答案 1 :(得分:6)

对于这种情况,使用Runtime.exec(String)是错误的方法(通常是将参数传递给新进程的错误方法)。

使用带有参数数组的one of the exec overloads 传递给新进程。 (或者,请参阅Paul对ProcessBuilder的回答 - 这些方法都不会遇到逃避问题)。

示例:

exec(new String[] { "vbomanager",
  "setextradata", "Test Machine",
  "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort", "2222"});

快乐的编码。

答案 2 :(得分:6)

您可能最好使用ProcessBuilder.command(arg0, arg1, ...)

,而不是尝试引用命令行

有关详细信息,请参阅ProcessBuilder

答案 3 :(得分:5)

在Windows上,Runtime.exec(String [])也不安全。如果参数数组包含空字符串,则基本上省略空参数,这可能导致命令行无效。此外,任何参数中的引号都不以反斜杠为前缀。此外,ProcessBuilder可以在不增加前面反斜杠数量的情况下添加引号,如果将路径传递给c:\ program files \等文件夹,包括尾部反斜杠,则会产生有趣的结果。

Microsoft的命令行标记器文档可在此处获得: http://msdn.microsoft.com/en-us/library/a1y7w461.aspx

我所描述的问题在此处记录: http://bugs.sun.com/view_bug.do?bug_id=6468220http://bugs.sun.com/view_bug.do?bug_id=6518827