Runtime exec() doesn't run commands when filename has spaces [duplicate] - java

This question already has answers here:
Java Runtime exec() fails to escape characters properly
(4 answers)
Closed 7 years ago.
I am new to Java and trying to convert one of my project from C to Java in order to combine it with another Java program. I'm having difficulty to get correct result when I use Runtime.exec(). I have the following program segment and Java ignores to process the given command.
command1 = "mv output/tsk/dir1/metabolic\\ waste.txt output/converted/file16.txt";
r2 = Runtime.getRuntime();
p2 = r2.exec(command1);
p2.waitFor();
The problem here is the filename "metabolic waste.txt". The same command work when there is no space. I know I have to use escape char for space and I do it. I'm working on Ubuntu btw.
I also tried using
String[] command1 = new String[] {"mv output/tsk/dir1/metabolic\ waste.txt", "output/converted/file16.txt";
but it didn't work.
p.s. the given code is just an example. I don't only use linux mv command. I also run some of the command line tools such as pdf2txt. I still have the same problem of running commands if there is any space in the filename.
SOLVED: I've solved my problem. It's ridiculous that I had to remove escape character and use string array. So, NO ESCAPE CHARACTER for space. The following code just worked for this example and for more general.
source_filepath = "output/tsk/dir1/metabolic waste.txt";
dest_filepath = "output/converted/file16.txt";
String[] str2= {"mv", source_filepath, dest_filepath};
r2 = Runtime.getRuntime().exec(str2);
p2.waitFor();

You have to escape the escape, or enclose the path in quotes:
String[] command1 = new String[] {"mv output/tsk/dir1/metabolic\\ waste.txt", "output/converted/file16.txt"};
String[] command1 = new String[] {"mv \"output/tsk/dir1/metabolic waste.txt\"", "output/converted/file16.txt"};
You have to use \\ because java also uses \ as an escape character, so "\\" really just contains one \

You can enclose the filename in double quotes as follows :
String srcFile = "output/tsk/dir1/metabolic\\ waste.txt"
command1 = "mv " + srcFile +" output/converted/file16.txt";

Related

How to replace String with different slashes? [duplicate]

This question already has answers here:
java split function
(6 answers)
Closed 7 years ago.
I need to rename some paths in database.
I rename folder:
String mainFolder= "D:\test\1\data"; //folder renamed from fd
Then i need to rename all files and directories inside that folder:
String file1="D:\test\1\fd\dr.jpg";
String folder1="D:\test\1\fd\fd"; // in this case last fd needs to be renamed
String folder2="src/fd/fd/"; //fake path also needs to be renamed
What is the best and fastest way to rename that strings?
My thoughts about "/":
String folder2= "src/da/da";
String[] splittedFakePath = folder2.split("/");
splittedFakePath[splittedFakePath.length - 2] = "data";
StringBuffer newFakePath = new StringBuffer();
for (String str : splittedFakePath) {
newFakePath.append(str).append("/");
}
String after rename: src/data/da/
But when im trying split by "\":
Arrays.toString(Pattern.compile(File.separator).split(folder1));
I receive:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
\
^
Look into java's String replace(...) method.
It is wonderful for string replacement, much better than attempting a regex.
Keep in mind that real directory handling has a few special cases, which don't lend themselves well to direct string manipulation. For example '//' often gets compacted to '/' in Unix like systems, and if you care about proper directory corner-cases, then use the Java Path class

How to overcome ArrayList String delimiting " " and ' '?

I have an array list defined as
List<String> cmd = new ArrayList<String>();
I am adding other strings to this List this way
cmd.add("/c");
cmd.add(command);
However if command contains " " or ' ' and a white space in between them the quotes are truncated.
How do I workaround this behaviour?
For example, if the command is
grep "Hello world" /sratch/temp
the cmd contains these Strings /c grep Hello World /scratch/temp
However if the command is grep "Hello\ world" /sratch/temp
the strings in cmd are
/c grep " Hello World " /scratch/temp
How do I program it such that the " " are not truncated?
So you want your String object to contain quotes? Try escaping them with backslash:
cmd.add("some string with \"quotes\"");
This problem is not related to ArrayList, you simple have to escape your single and double quotes when you assign them to the String object or retrieve them from user input. For more information on escape sequences in Java, have a look at this tutorial on the Oracle web site, for example.
This is actually not about Java, but about the shell you're using.
On the shell (i.e. bash, command prompt, etc.) arguments are generally broken up using spaces.
For instance,
java my.class The quick brown fox
would result in an argument list of
String[] { "The", "quick", "brown", "fox" }
However, the shell usually allows the user to make multiple spaced strings a single argument by surrounding them with double quotes - the behavior you're seeing.
For instance,
java my.class The quick "brown fox"
would result in an argument list of
String[] { "The", "quick", "brown fox" }
This means double quotes are removed from the argument list and are not literally inserted into the string.
If my assumption is correct, and you're running shell commands via your program given some sort of other command system, then you can simply surround every piece of the command in double quotes.
You can escape the quotes, just write:
"grep \"Hello world\" /sratch/temp"
You can take a look at this, for more information
EDIT
If you're parsing the user input Java will escape this special characters automatically. For example, with this code:
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
System.out.println("Input:"+s);
}
}
And the input: Testing "Quotes"
You will get this String:

Java how to handle a \ on input

I am currently trying to split a String folder. I get the value from a file system and it usually looks something like EAM\Testing.
String folder = "EAM\Testing"
String[] parts = folder.split("\\");
I know \ has special rules to it in java.
String folder = "EAM\\Testing"
String[] parts = folder.split("\\\\");
(I know the code above would work if I could control what the input looked like)
My problem is that I can not control what string folder is as input from a location of a file.
Is there a way to get this to work where folder only has one \ in it?
This is for a recycle bin component I am writing for Documentum a enterprise management system. When a document is deleted and the folder doesn't exist anymore I want to recreate it and inorder to recreate it the folder names must be seperate as I have to create them one at a time.
Here is how I get the name of the folder.
File f = new File(relationRecord.getRepeatingString(
"dp_original_folder_paths",
i));
(This gives an input such as \EAM\testing
String folder1 = f.toString();
I then get rid of the first \ by
String folder = folder1.substring(1);
Which gives me EAM\testing
Well if this is literally a file path, you should consider using the Path class, it'll make your life easier.
Path path = Paths.get("C:\\home\\joe\\foo");
System.out.format("toString: %s%n", path.toString());
System.out.format("getFileName: %s%n", path.getFileName());
System.out.format("getName(0): %s%n", path.getName(0));
System.out.format("getNameCount: %d%n", path.getNameCount());
System.out.format("subpath(0,2): %s%n", path.subpath(0,2));
System.out.format("getParent: %s%n", path.getParent());
System.out.format("getRoot: %s%n", path.getRoot());
Your second option
String[] parts = folder.split("\\\\");
Should work fine for your input string. When you write a string literal like "EAM\\Testing", the resulting string has only one slash. You can read some details on escape sequences in Java there.
The reason you need four slashes in split is because \ is an escape character both for string literals and regular expressions (String#split accepts regular expression as its argument)
You should be doing something like this -
String s = "EAM\\testing";
String a[] = s.split("\\\\");
Here you duplicate the backslash once for the String (since \ is an escape character for String) and again for the regex for the same reason.
Your question seems to be "how can I remove a leading \ from a string:
folder = folder.replaceAll("^\\\\", "");
This searches for a back slash at the start if the string, and if found replaces it with nothing (ie deletes it).
Regarding backslash vs forward slash characters in paths, java handles both.

space in path using java

Hi, I have a big problem. I'm making a java program and I have to call an exe file in a folder that have whitespace. This program also has 2 arguments that always have whitspace in the path.
Example:
C:\Users\Program File\convert image\convert.exe C:\users\image exe\image.jpeg C:\Users\out put\out.bmp
I have to do this in Windows but i want generalize it for every OS.
My code is:
Runtime run = Runtime.getRuntime();<br/>
String path_current = System.getProperty("user.dir");<br/>
String [] uno = new String[]{"cmd","/c",path_current+"\\\convert\\\convert.exe",path_current+"\\\f.jpeg", path_current+"\\\fr.bmp"};<br/>
Process proc2 = run.exec(uno);<br/>
proc2.waitFor();<br/>
This does not work. I tried removing the String array and inserting a simple String with "\"" before and after the path but that didn't work. How do I resolve this?
you may want to use :
http://commons.apache.org/io/api-1.4/org/apache/commons/io/FilenameUtils.html#separatorsToSystem(java.lang.String)
see also this answer :
Is there a Java utility which will convert a String path to use the correct File separator char?
Remove "cmd" and "/c", and use a single forward slash instead of your triple backslaches.

Spaces in java execute path for OS X

On OS X, I am trying to .exec something, but when a path contains a space, it doesn't work. I've tried surrounding the path with quotes, escaping the space, and even using \u0020.
For example, this works:
Runtime.getRuntime().exec("open /foldername/toast.sh");
But if there's a space, none of these work:
Runtime.getRuntime().exec("open /folder name/toast.sh");
Runtime.getRuntime().exec("open \"/folder name/toast.sh\"");
Runtime.getRuntime().exec("open /folder\\ name/toast.sh");
Runtime.getRuntime().exec("open /folder\u0020name/toast.sh");
Ideas?
Edit: Escaped backslash... still no worky.
There's a summary of this problem on Sun's forums... seems to be a pretty common issue not restricted to OS X.
The last post in the thread summarizes the proposed solution. In essence, use the form of Runtime.exec that takes a String[] array:
String[] args = new String[] { "open", "\"/folder name/toast.sh\"" };
or (the forum suggests this will work too)
String[] args = new String[] { "open", "folder name/toast.sh" };
Try this:
Runtime.getRuntime().exec("open /folder\\ name/toast.sh");
"\ " will just put a space in the string, but "\ " will put a "\ " in the string, which will be passed to the shell, and the shell will escape the space.
If that doesn't work, pass in the arguments as an array, one element for each argument. That way the shell doesn't get involved and you don't need bizarre escapes.
Runtime.getRuntime().exec(new String[]{"open", "/folder name/toast.sh"});
Paul's option works, but you still must escape the spaces like so:
Runtime.getRuntime().exec(new String[]{"open", "/folder\\ name/toast.sh"});
The thing that sucks about using a String array is that each param and its option must be in their own element. For instance you cannot do this:
Runtime.getRuntime().exec(new String[]{"executable", "-r -x 1", "/folder\\ name/somefile"});
But instead must specify it like so:
Runtime.getRuntime().exec(new String[]{"executable", "-r", "-x", "1", "/folder\\ name/somefile"});
In Kotlin, I was able to escape white spaces using templated strings.
private const val chromeExec = "/Applications/Google
Chrome.app/Contents/MacOS/Google Chrome"
Runtime.getRuntime().exec(arrayOf("$browserExec", url))

Categories