bug in "Runtime.getRuntime().exec()"

the command:

Runtime.getRuntime().exec("ln -s /home/Vvn/temp/a.txt /home/Vvn/temp/a\\ slnk.txt");

is never executed.

I figured out the problem. Java is not able to handle spaces in the filenames.

Simply using:

Runtime.getRuntime().exec("ln -s /home/Vvn/temp/a.txt /home/Vvn/temp/a\ slnk.txt");

will complain of a compilation error saying it as "illegal escape character. Hence i am forced to use "a\\ slnk.txt". but this should not be a problem because actually the string will be without the escape character when it is executed.

Can anyone let me know if you succeed in linking files having spaces in their filenames.

As a matter of fact ,if you can execute any other command (like "rm a\ slnk.txt" etc...) having spaces in the filenames. Please let me know.

Thank you. -Vvn

[838 byte] By [vvna] at [2007-11-27 6:11:11]
# 1

Obligatory pre-emptive Runtime.exec() link:

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

[Edit]: You might use the [url=http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html]exec(String[])[/url] form of the exec() call, to see if it solves your issue.

kevjavaa at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 2
Use quotes around what you don't want split. And are you sure it's Java that doesn't like spaces and not the OS? Of course you have to escape \ because \ is the escape char. \\ = \, \" = ", etc.
bsampieria at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 3

> I figured out the problem. Java is not able to handle

> spaces in the filenames.

This is incorrect.

\ might work, but you'd need two of them: \\ because \ is a special char in a Java string literal, so you need \\ so that the string passed to the command has a single \.

You might also try single or double quotes.

Or use one of the other exec signatures that takes the args as elements in an array.

jverda at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 4
And there's no need to escape forward slash -- to write \/
Hippolytea at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 5
And can I just add that it's quite annoying when somebody makes a couple of simple tests, doesn't really understand all the issues involved, and assumes it's a bug in Java and that Java can't handle such-and-such, rather than questioning his own knowledge and understanding.
jverda at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 6

Following is my program. Modify the code (the String lnk) and try compilation and execution to check if the thing worked.

Any help is appreciated.

Thank you -

Vvn

////////////////////////////////////////////////////////////////////////////////////////////

import java.io.*;

public class exec{

public static void main(String[] args){

String lnk = "ln -s /home/Vvn/temp/a.txt /home/Vvn/temp/a\\ slnk.txt";

String line;

try{

Process pro = Runtime.getRuntime().exec(lnk);

BufferedReader input = new BufferedReader(

new InputStreamReader(pro.getInputStream()));

while ((line = input.readLine()) != null) {

System.out.println(line);

}

input.close();

}catch(IOException ioe){

ioe.printStackTrace();

}

}

}

////////////////////////////////////////////////////////////////////////////////////////////

vvna at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 7

Easy!

import java.io.*;

public class Fred109_1

{

static public class SyncPipe implements Runnable

{

public SyncPipe(InputStream istrm, OutputStream ostrm)

{

istrm_ = istrm;

ostrm_= ostrm;

}

public void run()

{

try

{

final byte[] buffer = new byte[1024];

for (int length = 0; (length = istrm_.read(buffer)) != -1;)

{

ostrm_.write(buffer, 0, length);

}

}

catch (Exception e)

{

e.printStackTrace();

}

}

private final OutputStream ostrm_;

private final InputStream istrm_;

}

public static void main(String[] xargs) throws Exception

{

final String[] cmd =

{

"sh",

"-c",

"mkdir \"/home/sabre/f r e d.txt\"",

};

final Process p = Runtime.getRuntime().exec(cmd);

new Thread(new SyncPipe(p.getErrorStream(), System.err)).start();

new SyncPipe(p.getInputStream(), System.out).run();

int returnCode = p.waitFor();

}

}

sabre150a at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 8

> And can I just add that it's quite annoying when

> somebody makes a couple of simple tests, doesn't

> really understand all the issues involved, and

> assumes it's a bug in Java and that Java can't handle

> such-and-such, rather than questioning his own

> knowledge and understanding.

That requires a level of self-awareness and humbleness that the young programmer rarely exhibits. Of course, I know you know that already.

bsampieria at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 9

> Following is my program. Modify the code (the String

> lnk) and try compilation and execution to check if

> the thing worked.

No.

You read the advice you were given so far, try it out, and post again if you get stuck, with details about exactly what went wrong.

When you post code, please use[code] and [/code] tags as described in [url=http://forum.java.sun.com/help.jspa?sec=formatting]Formatting tips[/url] on the message entry page. It makes it much easier to read.

jverda at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 10
Please. I am talking about java here. Thank youVvn
vvna at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 11
> Please. I am talking about java here. > Thank you> VvnErr... what in #7 is not Java?
sabre150a at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 12
> Please. I am talking about java here. And...? Do you have a point?You're getting help, so don't complain about off-topic comments.
jverda at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 13
> Err... what in #7 is not Java?No, that's about shells and mkdir commands, silly!
bsampieria at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 14

It still does not work.

Thank you

Vvn

/////////////////////////////

import java.io.*;

public class exec{

public static void main(String[] args){

String lnk = "ln -s /home/Vvn/temp/a.txt /home/Vvn/temp/a\\ slnk.txt";

String[] cmd1 =

{

"ln",

"-s",

"\"/home/Vvn/temp/a.txt\"",

"\"/home/Vvn/temp/a slnk.txt\"",

};

String line;

try{

Process pro =Runtime.getRuntime().exec(cmd1);

BufferedReader input = new BufferedReader(

new InputStreamReader(pro.getInputStream()));

while ((line = input.readLine()) != null) {

System.out.println(line);

}

input.close();

}catch(IOException ioe){

ioe.printStackTrace();

}

}

}

vvna at 2007-7-12 17:17:19 > top of Java-index,Java Essentials,Java Programming...
# 15
> It still does not work.Please provide details of HOW it does not work.
jverda at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 16
the symbolic link(a slnk.txt) is not created even after execution.
vvna at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 17
One thing jumps out at me: It looks like you're combining a couple of different suggestions. Try one thing at a time. Take sabre's example and use it exactly as-is (except with a path that exists on your system). Then work on the differences between that and what doesn't work.
jverda at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 18
> > It still does not work.> > Please provide details of HOW it does not work.Man: So what does you father do?Boy: He's dead.Man: (awkward silence) Oh, what did he do before he died?Boy: Grabbed his chest and said "Auugghh!"
Hippolytea at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 19

> It still does not work.

Then you are doing it wrong because using my example withfinal String[] cmd =

{

"sh",

"-c",

"ln -s \"/home/sabre/f r e d.txt\" \"/home/sabre/b i l l.txt\"",

};

works great!

sabre150a at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 20
"sh"?
Hippolytea at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 21
> "sh"?shell.The bourne shell. IIRC, it's the only shell that's guranteed to be present on all Unices.
jverda at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 22
So are you saying "ln" is not a program but a shell builtin?
Hippolytea at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 23
> So are you saying "ln" is not a program but a shell> builtin?No. The -c arg to the sh command means "treat the rest of the command line as a command to run in the shell." It could be a builtin or it could be a command. (In the case of ln, it's a command.)
jverda at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 24

> It still does not work.

final String[] cmd =

{

"ln",

"-s",

"/home/sabre/f r e d.txt",

"/home/sabre/b i l l.txt",

};

also works great.

So - is there a bug in Runtime.exec() or do you just not understand it?

Message was edited by:

sabre150

sabre150a at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 25

hey sabre's thing works when i keep the sh , -c .all those .commands.

I was able to create the linked file. Thanks sabre and also jverd for patience.(i needed that).

I have one more question.

Is the command

Runtime.getRuntime().exec("ln -s /home/Vvn/a.txt /home/Vvn/b.txt");"

same as physically typing out the command "ln -s /home/Vvn/a.txt /home/Vvn/b.txt" on the shell?

I mean that does java runtime actully type these commands on the shell as they are?

vvna at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 26

> Is the command

> Runtime.getRuntime().exec("ln -s /home/Vvn/a.txt

> /home/Vvn/b.txt");"

> same as physically typing out the command "ln -s

> /home/Vvn/a.txt /home/Vvn/b.txt" on the shell?

No! The shell is not involved unless you explicitly invoke the shell as in "sh - c ....".

sabre150a at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 27

> hey sabre's thing works when i keep the sh , -c

I don't really think that's necessary, but I could be wrong. I did see another difference that I'm pretty sure would break it.

> Is the command

> Runtime.getRuntime().exec("ln -s /home/Vvn/a.txt

> /home/Vvn/b.txt");"

> same as physically typing out the command "ln -s

> /home/Vvn/a.txt /home/Vvn/b.txt" on the shell?

Not exactly. The shell does certain interpretations that aren't done by exec(). For instance if you use pipes, redirecting, backgrounding (|, >, &), etc., that stuff is interpreted by the shell, but not by exec(). If you want to do that stuff, you must use an appropriate shell-sh, bash, csh, etc.

There's also the issue of stdin, stdout, stderr. If you're in a console or terminal window (and this is really shell + console/terminal, not just shell), the command's stdin/out/err are connected to the shell, which in turn connects them to the terminal. If you want this kind of interaction through exec(), you'll need to have your Java program do something similar.

http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html

jverda at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 28
I meant that does the command say "Runtime.getRuntime().exec(ls -li)" is physically equivalent to typing out "ls -li" on the terminal(not in bash prompt..i.e..without the sh -c command)...(java does the typing of the command here)
vvna at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 29
I understand now. Thanks jverd.
vvna at 2007-7-21 21:45:15 > top of Java-index,Java Essentials,Java Programming...
# 30

> I meant that does the command say

> "Runtime.getRuntime().exec(ls -li)" is physically

> equivalent to typing out "ls -li" on the terminal(not

> in bash prompt..i.e..without the sh -c

> command)...(java does the typing of the command here)

I don't know what you mean.

Obviously there's no physical typing. Your keys are not being depressed, right?

When you do it interactively, you type on the keyboard, the keystrokes get sent to the window, which converts them to characters to send to the shell...

In Java if you just do "ln -s ...", it is, as I explained NOT the same as if you it at the console because there's no shell. If you do "sh -c 'ln -s...'" then it's almost identical. However there are some programs that care whether they're being run through an interactive terminal or not, and behave differently. For example, I don't think passwd will even work if it's not through a terminal.

jverda at 2007-7-21 21:45:20 > top of Java-index,Java Essentials,Java Programming...
# 31

I am going through all this because I have a program which has to delete duplicate files and create symbolic links in their place. I tried but could not find anything which can create a symbolic link in java(coded only in java..without using the Runtime(ln -s ....command).

Any help on this is greatly accepted.

Thank you

Vvn

vvna at 2007-7-21 21:45:20 > top of Java-index,Java Essentials,Java Programming...
# 32
If i used my program on a windows machine without modifying the Runtime...(ln -s ..command) then obviously it wouldn't work.
vvna at 2007-7-21 21:45:20 > top of Java-index,Java Essentials,Java Programming...
# 33

> If i used my program on a windows machine without

> modifying the Runtime...(ln -s ..command) then

> obviously it wouldn't work.

Since there are no soft links in windows then it won't work anyway! On windows useString[] command =

{

"cmd.exe",

"/C",

"commands you want to execute",

}

sabre150a at 2007-7-21 21:45:20 > top of Java-index,Java Essentials,Java Programming...
# 34

> That requires a level of self-awareness and

> humbleness that the young programmer rarely exhibits.

> Of course, I know you know that already.

I remember being like that.

I told the creator of a C++ compiler there was a bug in the compiler.

He told me I was wrong.

I pointed out that the example was from "The C++ Programming Language" by Stroustrup (first edition) that the compiler wasn't producing the result as stated in there.

The creator of the compiler told me that Stroustrup was wrong.

Not much that I could say after that....

jschella at 2007-7-21 21:45:20 > top of Java-index,Java Essentials,Java Programming...