Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Java's exec command when you don't know if there's be spaces

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.

like image 471
Dave Avatar asked Nov 01 '10 16:11

Dave


3 Answers

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:

String[] args = {"C:\Program Files\app\app.exe","C:\Data Files\data1.dat"};
Runtime.exec(args);

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.

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

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 the argarray. The proper solution is to get your users (or the input process) to properly differentiate all the arguments.

like image 70
Benn Avatar answered Oct 23 '22 11:10

Benn


Okay, I got something working by doing something like this. Please tell me if there's a problem with this approach:


try{
    String[] command = {"cmd", "/c", getMySuperAwesomeString()};
    Runtime.getRuntime().exec(command);
}catch(IOExecption ioe){
    System.err.println("I'm borken");
}

On a related note, should I use ProcessBuilder instead?

like image 25
Dave Avatar answered Oct 23 '22 09:10

Dave


Example to run a JAR file with spaces in the file location:

String qoutation = "\""
String path = "C:\\JAR File\\File.jar"
Runtime.getRuntime().exec("java -jar " + quotation + path + quotation);

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.

like image 27
KronosDEV Avatar answered Oct 23 '22 10:10

KronosDEV