当你不知道是否有空格时使用Java的exec命令
我正在与 Java 的运行时 exec 方法中的空格错误作斗争。这个问题的独特之处在于:我尝试执行的命令是一个传入字符串,可能有也可能没有空格,并且不一定采用任何特定格式。不管怎样,我都需要执行它。如果没有空格,我就很好;如果有空格,我就不太好。
我如何解释这两种情况?
无需额外付费的额外信息:最大的问题之一似乎是我试图在 c:\program files\blablabla 中调用可执行文件...并且 exec 似乎在“c:\program”之后的空间上分割。我确信参数也会出现其他问题。
这是我可能得到的字符串类型的更具体示例。这应该可以消除一些混乱:
- c:\someApp\someapp.exe
- c:\someApp\someapp.exe -someParam=foo
- c:\program files\someapp\someapp.exe
- c:\program files\someapp\someapp。 exe -someParam=bar
第一个工作正常,因为它没有空格。第二个甚至还可以,因为它在空间上分开并使用第一个作为命令,第二个作为参数。第三个和第四个示例在第一个空格上分开,使用“C:\program”和命令“files...”以及(在第四个字符串的情况下)“-someParam=bar”作为参数。
I'm fighting the spaces bug in Java's Runtime exec method. Here's what's unique about this problem: the command I'm trying to execute is an incoming string and may or may not have spaces and is not necessarily in any specific format. Either way, I need to execute it. If there are no spaces, I'm good; if there are spaces, I'm not so good.
How do I account for both circumstances?
Bonus info at no extra charge: One of the big issues appears to be that I'm trying to call an executable in c:\program files\blablabla... and exec appears to split on the space after 'c:\program'. I'm sure other issues would come up for the parameters, too.
Here's a more specific example of the kinds of strings I might get. That should clear up some of the confusion:
- c:\someApp\someapp.exe
- c:\someApp\someapp.exe -someParam=foo
- c:\program files\someapp\someapp.exe
- c:\program files\someapp\someapp.exe -someParam=bar
The first one works fine because it has no spaces. The second is even okay because it splits on the space and uses the first as a command and second as a parameter. The third and fourth examples split on the first space, use 'C:\program' and the command, 'files...' and (in the case of the fourth string) '-someParam=bar' as parameters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我实际上会将其作为答案而不是评论:
(从 J2SE 1.5 开始,Runtime.exec(String[]))
假设您可以预处理,使用字符串数组来缓解命令中空格的问题,以下应该可以工作:
从那里它取决于能够找出两个命令之间的空格以及路径中的空格。
编辑
如果空格出现在可执行文件的路径中,这将起作用,但不会帮助您处理参数中的空格。
请注意,这仍然相当脆弱(并且仅适用于 exe,不适用于 bat 或其他任何文件)。如果您需要考虑参数中的空格,则需要对
args
字符串或argarray
进行更多处理。正确的解决方案是让您的用户(或输入过程)正确区分所有参数。I'll actually make this an answer instead of a comment:
(from the J2SE 1.5, Runtime.exec(String[]))
Assuming you can preprocess, use a String array to alleviate the problems with spaces in commands, the following should work:
From there it depends on being able to figure out what is a space between two commands and what is a space in a path.
EDIT
This will work if the spaces appear in the executable's path, but won't help you on spaces in the arguments.
Note that this is still fairly fragile (and only works for exe's, not bat's or whatever else). If you need to account for spaces in the arguments, you'll need to do more processing to either the
args
string or theargarray
. The proper solution is to get your users (or the input process) to properly differentiate all the arguments.好吧,我通过做这样的事情得到了一些东西。请告诉我这种方法是否有问题:
在相关说明中,我应该使用 ProcessBuilder 吗?
Okay, I got something working by doing something like this. Please tell me if there's a problem with this approach:
On a related note, should I use ProcessBuilder instead?
运行文件位置中包含空格的 JAR 文件的示例:
运行命令: java -jar "C:\Jar File\File.jar"
当反斜杠 \ 出现在字符串中时,它被用作转义符,有效地使程序跳过它。这允许我们在字符串中使用引号 ",而不是开始/结束字符串。
Example to run a JAR file with spaces in the file location:
This runs the command: java -jar "C:\Jar File\File.jar"
When the backslash \ appears in a string it is used as an escape, effectively making the program skip it. This allows us to use the quotation mark " in the string, not to start/close the string.
也许我想得太简单了,但这可行吗?
(我假设您希望像在 shell 等中执行一样执行该命令。)
Maybe I'm thinking too simply, but could this work?
(I'm assuming that you want the command to be executed as if executed in a shell or so.)
我假设您可以预处理传入的字符串。在这种情况下,您可以通过以下方式查看输入是否包含空格:
请注意,仅当输入中存在实际空格字符时,这才有效。如果您想更彻底,假设制表符或换行符是可能的输入,您可以使用正则表达式:
编辑:您可以使用我提供的代码来检测输入中是否有空格。如果没有,您无需执行任何操作。如果有空间,情况会更复杂一些。阅读其他人的答案和您修改后的问题,我只能假设必须引用包含空格的输入,因此空格不会扰乱标准命令执行。如果有空格,您应该:
"
更改为\"
)some input
变为"some input"
)最终,您希望像
some "funky" input
这样的输入变为"some \"时髦的“输入”
。注意:注意单引号 (
'
)。适当地处理他们。I'll assume you can preprocess the incoming string. In that case, you can see if you have an input with spaces with:
Note that this will work only if there's an actual space character in your input. If you want to be more thorough, assuming tab characters or newlines are possible inputs, you can use a regex:
Edit: You can use the code I provided to detect if there are spaces in the input. If there aren't, you don't have to do anything. If you have spaces, the situation is a bit more complex. Reading other people's answers and your revised question, I can only assume that the input that has spaces has to be quoted, so spacing won't mess up the standard command execution. In there are spaces, you should:
"
to\"
)some input
becomes"some input"
)Ultimately, you want input like
some "funky" input
to become"some \"funky\" input"
.Note: beware of single quotes (
'
). Deal with them appropriately.我假设这是您正在对抗的错误:
https://bugs.java.com /bugdatabase/view_bug?bug_id=4506936
https:// bugs.java.com/bugdatabase/view_bug;jsessionid=8582245ba20fa4da33ac0967e858?bug_id=4491217
他们说解决方法是:
使用不位于包含空格的路径中的 JRE。
使用
公共进程执行(字符串[] cmdarray,
字符串[] envp)
抛出 IOException
并将命令和参数放入单独的数组中。这样它就不会尝试对其进行标记并使用空格作为分隔符。
I am assuming this is the bug you are fighting:
https://bugs.java.com/bugdatabase/view_bug?bug_id=4506936
https://bugs.java.com/bugdatabase/view_bug;jsessionid=8582245ba20fa4da33ac0967e858?bug_id=4491217
They say that the workaround would be:
Use a JRE that is not located in a path that contains spaces.
Use
public Process exec(String[] cmdarray,
String[] envp)
throws IOException
and put the command and parameters in a separate array. This way it wouldn't try to tockenize it and use space as a separator.