12

I can execute Linux commands like ls or pwd from Java without problems but couldn't get a Python script executed.

This is my code:

Process p;
try{
    System.out.println("SEND");
    String cmd = "/bash/bin -c echo password| python script.py '" + packet.toString() + "'";
    //System.out.println(cmd);
    p = Runtime.getRuntime().exec(cmd); 
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String s = br.readLine(); 
    System.out.println(s);
    System.out.println("Sent");
    p.waitFor();
    p.destroy();
} catch (Exception e) {}

Nothing happened. It reached SEND but it just stopped after it...

I am trying to execute a script which needs root permissions because it uses serial port. Also, I have to pass a string with some parameters (packet).

Paul Verest
  • 60,022
  • 51
  • 208
  • 332
Biribu
  • 3,615
  • 13
  • 43
  • 79

4 Answers4

18

You cannot use the PIPE inside the Runtime.getRuntime().exec() as you do in your example. PIPE is part of the shell.

You could do either

  • Put your command to a shell script and execute that shell script with .exec() or
  • You can do something similar to the following

    String[] cmd = {
            "/bin/bash",
            "-c",
            "echo password | python script.py '" + packet.toString() + "'"
        };
    Runtime.getRuntime().exec(cmd);
    
Alper
  • 12,860
  • 2
  • 31
  • 41
  • How do I do a shell script for that? I have never created a shell script – Biribu May 08 '13 at 18:37
  • 2
    This answer works even without creating a shell script file. Just copy-paste it to your code. – pts May 08 '13 at 18:43
  • @pts Yes, it works but I couldn't explain it clearly before. I updated the post, I hope it better now. – Alper May 08 '13 at 19:19
  • I have a two python versions running in my system. one the default one for which I have set the env path variable, the other one is from anaconda package which is in different location for instance (c:/Users/Nitesh/appdata/anaconda/python.exe) I want this python which is given by anaconda to run the python script through java. What should I give in the array of string cmd. I tried changing the 2 element (-c) to the fully qualified path of my anaconda python, It didn't work yet. – Nitesh kumar Nov 22 '16 at 12:34
  • Is it good practice to call scripts from JAVA? Any performance issues? – kautuksahni Sep 18 '17 at 05:58
12

@Alper's answer should work. Better yet, though, don't use a shell script and redirection at all. You can write the password directly to the process' stdin using the (confusingly named) Process.getOutputStream().

Process p = Runtime.exec(
    new String[]{"python", "script.py", packet.toString()});

BufferedWriter writer = new BufferedWriter(
    new OutputStreamWriter(p.getOutputStream()));

writer.write("password");
writer.newLine();
writer.close();
NatNgs
  • 874
  • 14
  • 25
jtahlborn
  • 52,909
  • 5
  • 76
  • 118
7

You would do worse than to try embedding jython and executing your script. A simple example should help:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");

// Using the eval() method on the engine causes a direct
// interpretataion and execution of the code string passed into it
engine.eval("import sys");
engine.eval("print sys");

If you need further help, leave a comment. This does not create an additional process.

hd1
  • 33,938
  • 5
  • 80
  • 91
0

First, open terminal and type "which python3". You will get the complete path of python3. For example "/usr/local/bin/python3"

String[] cmd = {"/usr/local/bin/python3", "arg1", "arg2"};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();

String line = "", output = "";
StringBuilder sb = new StringBuilder();

BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine())!= null) {sb = sb.append(line).append("\n"); }

output = sb.toString();
System.out.println(output);