0

With this, we can execute "build in" commands in java. However if we want to run some custom commands from this, Changing "pwd" to "device_id -l" doesn't work. "device_id -l" should list all the ids of attached devices of currently host. if "device_id -l" is executed in terminal itself. it works fine. There is not a question for the "build in" bash commands. Thank you.

    String cmd = "pwd";
    Runtime run = Runtime.getRuntime();
    Process pr = run.exec(cmd);      
    pr.waitFor();

    BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
    String line = "";
    while ((line=buf.readLine())!=null)      
        System.out.println(line);

We can excuate

Giancarlo Romeo
  • 663
  • 1
  • 9
  • 24
Dmomo
  • 83
  • 1
  • 1
  • 12
  • What does it mean "it doesn't work"? What is the error that is reported? – Neeme Praks Mar 08 '15 at 21:04
  • updated the path to:"/Users/guohua.xie/libimobiledevice-macosx/idevice_id" dyld: Library not loaded: @executable_path/../lib/libimobiledevice.3.dylib Referenced from: /Users/userName/libimobiledevice-macosx/idevice_id Reason: image not found – Dmomo Mar 08 '15 at 21:35
  • Are you sure the user that is executing the Java process has proper permissions? – Neeme Praks Mar 08 '15 at 21:36
  • I believe so. since this user can execute it in terminal. – Dmomo Mar 08 '15 at 21:38
  • Ok, if you have "Library not loaded" then we are getting somewhere. I suspect the DYLD_LIBRARY_PATH environment variable is not getting passed from parent process to child process (for whatever reason). Try experimenting with ProcessBuilder.environment(). – Neeme Praks Mar 08 '15 at 21:48
  • Also you can check if that environment variable is set at all in your Java process (System.getenv()). And, you can check what is the value of that variable in shell (and if they differ). – Neeme Praks Mar 08 '15 at 21:50
  • It could also be a 32bit vs 64bit thing ("image not found" seems to suggest that it is able to locate the correct dylib, but unable to find the correct image from that library). I assume you are using a 64bit JVM and maybe Java is executing the sub-process with same architecture (a stab in the dark). You can try "-d32" command line argument to the JVM and see if it makes any difference. – Neeme Praks Mar 08 '15 at 22:03

2 Answers2

0

You can try using ProcessBuilder.

// create process
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "device_id", "-l");
// start process
Process p = pb.start();
// wait for process exit
p.waitFor();

// read process output
BufferedReader buf = new BufferedReader(newInputStreamReader(p.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null)
    System.out.println(line);
Giancarlo Romeo
  • 663
  • 1
  • 9
  • 24
  • 1
    If we want to > the result to a file. We can do: ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "device_id", "-l",">","result.txt"); @Giancarlo Remeo – Dmomo Mar 08 '15 at 21:27
  • Why not just http://stackoverflow.com/questions/16238714/runtimes-exec-method-is-not-redirecting-the-output – Neeme Praks Mar 08 '15 at 21:33
  • @ Neeme Parks It is a solution, the example is to run a script, but a command. which means i need to write a script to run the command as a wrapper. but wonder if we can just execute custom command. since I know that Node.js can by var sys = require('sys'); var exec = require('child_process').exec; var child = exec("idevice_id -l > result.txt", function (error, stdout, stderr) { + stdout); console.log('stderr: ' + stderr); if (error !== null) { console.log('exec error: ' + error); } }); – Dmomo Mar 08 '15 at 23:33
  • @ Giancarlo Romeo. Thank you, as well. same error message. dyld: Library not loaded: @executable_path/../lib/libimobiledevice.3.dylib Referenced from: /Users/userName/libimobiledevice-macosx/idevice_id Reason: image not found – Dmomo Mar 08 '15 at 23:36
0

You need to split your command+arguments to a String array. In your case, if you want to execute "device_id -l", split that into an array like this:

String[] cmd = new String[] {"/full/path/to/device_id", "-l"};
Process pr = Runtime.getRuntime().exec(cmd);

And, you might want to use ProcessBuilder.

String[] cmd = new String[] {"/full/path/to/device_id", "-l"};
ProcessBuilder pb = new ProcessBuilder(cmd);
Process pr = pb.start();

Finally, you'll have to take into account that Java does not look for executables in PATH (like command shell does), you'll have to provide full path to the executable/script that you want to execute (or it has to be in the working directory; you can set the working directory with ProcessBuilder.directory(File)).

See also: Difference between ProcessBuilder and Runtime.exec()

Community
  • 1
  • 1
Neeme Praks
  • 8,956
  • 5
  • 47
  • 47
  • "Java does not look for executables in PATH (like command shell does)" Really? Works for me. – dnault Mar 08 '15 at 21:11
  • Oh yeah? Give me a source on the web or a piece of code to prove otherwise. – Neeme Praks Mar 08 '15 at 21:12
  • There is a workaround hack mentioned here: http://stackoverflow.com/questions/6984138/path-variable-isnt-inherited-through-getruntime-exec (I haven't tried it, not sure if it will work). – Neeme Praks Mar 08 '15 at 21:22
  • Or you can just execute "/bin/bash" and add your command as an argument (like in the other answer). As that is ran through bash (and bash supports PATH), it will work. However, that will make you dependent on bash (e.g. will not work on Windows). – Neeme Praks Mar 08 '15 at 21:24
  • @ Neeme Prakks, It doesn't work. Nice try and thank you. – Dmomo Mar 08 '15 at 21:29
  • What doesn't work? Please update your question with the error that you get. Otherwise all this is just wandering in the dark. – Neeme Praks Mar 08 '15 at 21:31