我正在与Java的Runtime exec方法中的space bug进行斗争。这是这个问题的独特之处:我试图执行的命令是一个传入的字符串,可能有也可能没有空格,不一定是任何特定的格式。无论哪种方式,我都需要执行它。如果没有空格,我很好;如果有空格,我就不太好了。
我如何解释这两种情况?
免费获得奖励信息:其中一个重要问题似乎是我试图在c:\ program files \ blablabla中调用可执行文件......并且exec似乎在'c:之后的空格上拆分: \程序'。我也确定参数的其他问题也会出现。
这是我可能得到的各种字符串的更具体的例子。这应该可以解决一些困惑:
第一个工作正常,因为它没有空格。第二个甚至可以,因为它在空间上分裂并使用第一个作为命令,第二个作为参数。第三个和第四个例子在第一个空格上分开,使用'C:\ program'和命令,'files ...'和(在第四个字符串的情况下)'-someParam = bar'作为参数。
答案 0 :(得分:4)
我实际上会将此作为答案而不是评论: (来自J2SE 1.5,Runtime.exec(String[]))
假设您可以预处理,使用String数组来缓解命令中的空格问题,以下内容应该有效:
String[] args = {"C:\Program Files\app\app.exe","C:\Data Files\data1.dat"};
Runtime.exec(args);
从那里,它取决于能够弄清楚两个命令之间的空间是什么,以及路径中的空间是什么。
修改强>
如果空格出现在可执行文件的路径中,这将有效,但不会帮助您处理参数中的空格。
String input = "c:\\program files\\someapp\\someapp.exe -someParam=bar";
int firstSplit = input.indexOf(".exe") + 4; //account for length of ".exe"
String command = input.substring(0,firstSplit);
String args = input.substring(firstSplit).trim(); //trim off extraneous whitespace
String[] argarray = args.split(" ");
String[] cmdargs = new String[argarray.length + 1];
cmdargs[0] = command;
for (int i = 0; i < argarray.length; i++) {
cmdargs[i+1] = argarray[i];
}
Runtime.exec(cmdargs);
请注意,这仍然相当脆弱(仅适用于exe,而不是bat或其他任何东西)。如果您需要在参数中考虑空格,则需要对args
字符串或argarray
进行更多处理。正确的解决方案是让您的用户(或输入过程)正确区分所有参数。
答案 1 :(得分:4)
好的,我做了类似的工作。请告诉我这种方法是否有问题:
try{
String[] command = {"cmd", "/c", getMySuperAwesomeString()};
Runtime.getRuntime().exec(command);
}catch(IOExecption ioe){
System.err.println("I'm borken");
}
在相关的说明中,我应该使用ProcessBuilder吗?
答案 2 :(得分:1)
在文件位置运行带空格的JAR文件的示例:
String qoutation = "\""
String path = "C:\\JAR File\\File.jar"
Runtime.getRuntime().exec("java -jar " + quotation + path + quotation);
这将运行命令:java -jar“C:\ Jar File \ File.jar”
当反斜杠\出现在字符串中时,它被用作转义符,有效地使程序跳过它。这允许我们在字符串中使用引号“,而不是开始/关闭字符串。
答案 3 :(得分:0)
也许我的想法太简单了,但这可行吗?
Runtime.exec(commandstring.split(" "));
(我假设您希望执行该命令,就好像在shell中执行一样。)
答案 4 :(得分:0)
我假设您可以预处理传入的字符串。在这种情况下,您可以看到输入的空格是否为:
if("string with possible spaces".contains(" ")) {
System.out.println("yay");
}
请注意,仅当输入中有实际的空格字符时,这才有效。如果你想更加彻底,假设标签字符或换行符是可能的输入,你可以使用正则表达式:
String s = ".+\\s.+";
Pattern p = Pattern.compile(s);
Matcher m = p.matcher("string with possible spaces or tabs");
if(m.matches()) {
System.out.println("yay");
}
编辑:您可以使用我提供的代码来检测输入中是否有空格。如果没有,您不必做任何事情。如果你有空格,情况会有点复杂。阅读其他人的答案和修改后的问题,我只能假设必须引用具有空格的输入,因此间距不会弄乱标准命令执行。如果有空格,你应该:
"
更改为\"
)some input
变为"some input"
)最终,您希望some "funky" input
之类的输入成为"some \"funky\" input"
。
注意:注意单引号('
)。适当地处理它们。
答案 5 :(得分:0)
我假设这是你正在战斗的错误:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4506936
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=8582245ba20fa4da33ac0967e858?bug_id=4491217
他们说解决方法是:
使用不在包含空格的路径中的JRE。
使用 public Process exec(String [] cmdarray, String [] envp) 抛出IOException
并将命令和参数放在一个单独的数组中。这样它就不会试图将它tockenize并使用space作为分隔符。