2

I am trying to execute in linux:

command[0] = "~/test/bin/runScript_sh";
Runtime.getRuntime().exec(command);

But get an exception java.io.IOException: Cannot run program
error=2, No such file or directory

Probably because it can not evaluate tilde.

What can be done?

yuris
  • 1,109
  • 4
  • 19
  • 33

4 Answers4

4

I would replace it myself.

if(path.s.substring(0,1).contains("~"))
    path = path.replaceFirst("~",System.getProperty("user.home"));

Which gets you the string you want.

Tuim
  • 2,491
  • 1
  • 14
  • 31
2

You can get the user's home directory with System.getProperty:

command[0] = System.getProperty("user.home") + "/test/bin/runScript_sh";
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
  • Prefer replacing ~ over prepending to the command. command[0] can be user input. This way you could get `/home/username/~/test/bin/runScript.sh` – Tuim Mar 07 '13 at 14:25
  • Tuim, that is not a very good idea. How does the user input a path actually containing a tilde character in that case (since it may very well be a valid path character)? Or even worse, you may give the user the impression that she can use shell semantics for the path, which may result in trying `~emil` and similar constructs. I prefer building stuff myself in these cases. – Emil Vikström Mar 07 '13 at 14:49
  • You are right, and I have updated my answer. But then again which sane person uses ~ in the path name. – Tuim Mar 07 '13 at 14:54
2

When you run a command at the shell command prompt, things like ~ expansion, quote handling, globbing, $variable expansion, input/output redirection and piping and son on are all handled by the shell ... before it asks the operating system to run the program(s) for you.

When you run a command using Runtime.exec, you have three choices:

  • write the command without any shell "funky stuff"
  • replicate what the shell would do in Java; e.g. replace leading tildes with the appropriate stuff1, or
  • use exec to launch a child shell to run the command; e.g.

    Runtime.getRuntime().exec("/bin/sh", "-c", "~/test/bin/runScript_sh");
    

    That is possibly overkill in a simple case like this. But if you are trying to do more complicated things then a child shell can really simplify things.


1 - In fact fully shell compatible handing of tildes is fairly complicated.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

Items such as ~ and $HOME are shell expansions

You have to expand these items in your program and then replace them (hint: get them from the os properties, see this page)

KevinDTimm
  • 14,226
  • 3
  • 42
  • 60