Reputation: 17119
I'm trying to run the following code to swap filenames. I'm using Runtime.exec
. The code throws IOException
. Anyway to fix this?
try {
Runtime.getRuntime().exec("file1=" + folderpath + " && file2=/mnt/sdcard/fsimages && temp=\"$(/system/xbin/mktemp -dp /mnt/sdcard)\" && /system/xbin/mv \"$file1\" $temp && /system/xbin/mv \"$file2\" \"$file1\" && /system/xbin/mv $temp/\"$file1\" \"$file2\"");
} catch (IOException e) {
e.printStackTrace();
return;
}
And the error:
02-28 07:48:02.936: W/System.err(14399): java.io.IOException: Error running exec(). Command: [file1=/mnt/sdcard/fsimages_3, &&, file2=/mnt/sdcard/fsimages, &&, temp="$(/system/xbin/mktemp, -dp, /mnt/sdcard)", &&, /system/xbin/mv, "$file1", $temp, &&, /system/xbin/mv, "$file2", "$file1", &&, /system/xbin/mv, $temp/"$file1", "$file2"] Working Directory: null Environment: null
It looks like Runtime.exec is inserting a coma before and after every &&. Seems like the issue is in the way which Runtime.exec interprets &&. Why is this happening? How can I prevent this?
Upvotes: 4
Views: 13389
Reputation: 718886
If you use the Runtime.exec(String)
overload, the string is treated as a command and its arguments, and is crudely split into substrings at white-space boundaries. This splitting is standard behaviour for that overload. (Refer to the javadoc.)
Runtime.exec(...)
expects a native command and its arguments. You've provided a line of shell input. The exec methods don't understand shell input and don't know how to execute it properly. And the crude splitting (see above) messes up everything.
If you need to do that, then use the following:
String yourShellInput = "echo hi && echo ho"; // or whatever ...
String[] commandAndArgs = new String[]{ "/bin/sh", "-c", yourShellInput };
Runtime.getRuntime().exec(commandAndArgs);
This is equivalent to running:
$ /bin/sh -c "echo hi && echo ho".
If sh
is not installed as /bin/sh
use the path where it is installed instead.
Upvotes: 14
Reputation: 1410
First of all the problem is not what you think "It looks like Runtime.exec is inserting a comma before and after every &&" actually the error statement is reporting your command that you gave in Runtime.exec() as String array (String[]). This is a standard behaviour of Java Runtime.exec() method.
02-28 07:48:02.936:
W/System.err(14399): java.io.IOException:
Error runningexec(). Command:
[file1=/mnt/sdcard/fsimages_3, &&, file2=/mnt/sdcard/fsimages, &&, temp="$(/system/xbin/mktemp, -dp, /mnt/sdcard)", &&, /system/xbin/mv, "$file1", $temp, &&, /system/xbin/mv, "$file2", "$file1", &&, /system/xbin/mv, $temp/"$file1", "$file2"]
Working Directory: null Environment: null
You can see in the error how Java interprets your command which you hardcoded, the String array you are getting back shows you that "file1=/mnt/sdcard/fsimages_3" is treated as opening command to execute and the rest " &&" , "file2=/mnt/sdcard/fsimages" etc. is treated as arguments.
What I think you should do is first try to split your command in an array like structure. as an example below
Process process;
String[] commandAndArgs = new String[]{ "/bin/sh", "mv", "/mnt/sdcard/fsimages_3","/mnt/sdcard/fsimages" };
process = Runtime.getRuntime().exec(commandAndArgs);
Next, your error shows that your working directory is null and your Environment is also null. So you need to set both of them for your process. From Java docs you can see it states this exec() overloaded method
exec(String[] cmdarray, String[] envp, File dir)
Executes the specified command and arguments in a separate process with the specified environment and working directory.
In case nothing stated works, I request you to kindly write a shell script file for your command and then set it executable using
chmod 755 or chmod +x script.sh;
then try to run that. I hope it works as in my case the script file approach worked.
Upvotes: 4