Java 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");

它返回一个错误:未注册的 vm '“TestMachine”'

对于其中有空格的参数(如Test\Machine)也是如此,然后它不会转义空格。

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


答案 1

您一次性调用程序及其参数,这有效地将整个字符串推入处理环境(希望获得最佳效果)。

在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

充其量,使用one string方法,您最终会找到如何提示和转义参数,以便它们不会被视为可执行文件名称的一部分,但随后您会遇到一个新问题,即它们将全部作为一个参数传递给可执行文件。一旦你根据环境修复了这个问题,你就会发现你的引号没有从参数中剥离(导致像“2222”这样的参数),或者Window的半中断参数解析将首先解析空格(导致像(“测试”)这样的参数)。这是没有道理的,这就是为什么有多种方法可用。exec


答案 2

在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