Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala run process on different working dir

I can't use Process("dir/e.exe") because e needs to be executed on its own directory, if not it can't access to its resources. But i receive an exception whenever i try to change the working directory:

Process("e.exe", new File(dir)) 
Process("e.exe", new File("\"+ dir))
Process("e.exe", new File(new File(dir).getCanonicalPath()))  

Caused by: java.io.IOException: Cannot run program "e.exe" (in directory ".
\dir"): CreateProcess error=2, The system cannot find the file specified

These do not work, they give me exactly the same error. Any alternative?

EDIT: This is how looks my directory:

MyFolder:
|-app.jar
|-folderWithExe
  \-e.exe
like image 611
Wlofrevo Kcast Avatar asked Sep 09 '13 16:09

Wlofrevo Kcast


2 Answers

Okay, that's what I have (dirty code, just for demo purposes)

First, my directory structure (subdir is a subdirectory):

cdshines@v3700:~/test|⇒  ls -R
.:
log  pb.scala  subdir

./subdir:
ls

Then my code:

import java.lang.ProcessBuilder
import java.io.File

val pb = new ProcessBuilder("ls", "../")
pb.directory(new File("subdir"))
pb.redirectOutput(ProcessBuilder.Redirect.to(new File("log")))
val p = pb.start
p.waitFor
println(p.exitValue)

Let's see:

cdshines@v3700:~/test|⇒  scala pb.scala
0
cdshines@v3700:~/test|⇒  cat log
log
pb.scala
subdir

Is that what you expect from this code? Looks fine to me.

In general:

1) create ProcessBulder using new ProcessBuilder("application", "arg0", "arg1")

2) set its directory by "pb.directory(new File("path/to/dir"))"

3) get output or exit codes and so on with either Process or ProcessBuilder methods.

With Scala, you may use Source to make it a little bit faster to write (even more dirtier, but is good enough to play around):

scala.io.Source.fromInputStream(
  new ProcessBuilder("ls", "../")
  .directory(new File("subdir"))
  .start
  .getInputStream).getLines.mkString("\n")
like image 123
tkroman Avatar answered Nov 03 '22 19:11

tkroman


Try "./e.exe" or put "." on the path.

(Edited for clarity.)

Postmortem: the question is, what could you do to solve this quickly without SO? You really want a message that says: "Couldn't find the program to run after trying these locations..." Or even, perhaps under something like -Dprocess.debug, "There is a file named foo in the current directory but I can't run it because..."

For the record:

import sys.process._
import java.io.File

//System setSecurityManager new SecurityManager
Console println Process("./tester", new File("subdir")).lines.toList

Showing that path matters:

apm@mara:~/tmp/cdtest$ echo $PATH
/home/apm/go1.1/go/bin:/home/apm/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
apm@mara:~/tmp/cdtest$ vi runit.scala
apm@mara:~/tmp/cdtest$ scalam runit.scala
java.io.IOException: Cannot run program "tester" (in directory "subdir"): error=2, No such file or directory
apm@mara:~/tmp/cdtest$ grep tester runit.scala 
Console println Process("tester", new File("subdir")).lines.toList
apm@mara:~/tmp/cdtest$ PATH=$PATH:.
apm@mara:~/tmp/cdtest$ scalam runit.scala
List(file1, file2, tester)
like image 42
som-snytt Avatar answered Nov 03 '22 18:11

som-snytt