So trying to use "cp" to copy a file from one location to another - the file is denominated with a file name containing white space ("test test"). When invoking command in the shell (bash) it works fine, but called from java it fails. I use escape characters. Code:
import java.io.*;
public class Test {
private static String shellify(String path) {
String ret = path;
System.out.println("shellify got: " + ret);
ret = ret.replace(" ", "\\ ");
System.out.println("shellify returns: " + ret);
return ret;
}
private static boolean copy(String source, String target) {
String the_command = ""; // will be global later
boolean ret = false;
try {
Runtime rt = Runtime.getRuntime();
String source_sh = shellify(source);
String target_sh = shellify(target);
the_command = new String
("cp -vf " + source_sh + " " + target_sh);
System.out.println("copy execing: " + the_command);
Process p = rt.exec(the_command);
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader
(new InputStreamReader(is));
String reply = br.readLine();
System.out.println("Outcome; " + reply);
ret = (reply != null) && reply.contains("->");
} catch(Exception e) {
System.out.println(e.getMessage());
}
the_command = "";
return ret;
}
public static void main(String[] args) {
String source = "test1/test test";
String target = "test2/test test";
if(copy(source, target))
System.out.println("Copy was successful");
else
System.out.println("Copy failed");
}
}
...and the outcome is this
shellify got: test1/test test
shellify returns: test1/test\ test
shellify got: test2/test test
shellify returns: test2/test\ test
copy execing: cp -vf test1/test\ test test2/test\ test
Outcome; null
Copy failed
whereas if I use bash the copy succeeded (big surprise).
Sino-Logic-IV:bildbackup dr_xemacs$ cp -vf test1/test\ test test2/test\ test
test1/test test -> test2/test test
Can anyone please tell me why this is? Copying files without white spaces works just fine.
/dr_xemacs
You should pass the arguments individually and they do not need escaping in shellify because the String[] version of exec provides each argument to the script separately as one argument even if they contain spaces:
String[]the_command = new String[] {"cp","-vf", source, target);
You may need to fix PATH available to Java VM if cp
is not present in one of the PATH directories, or you could fully qualify the path to the executable cp in the_command [0]
.
Your code is missing a line to check the cp
/ process exit code, add waitFor
after consuming the STDOUT / getInputStream()
:
int rc = p.waitFor();