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).

2
  • is your python script writing somethong to it's standard out? Commented May 8, 2013 at 18:15
  • What about use Apache commons exec ? Commented May 8, 2013 at 18:20

4 Answers 4

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);
    
Sign up to request clarification or add additional context in comments.

5 Comments

How do I do a shell script for that? I have never created a shell script
This answer works even without creating a shell script file. Just copy-paste it to your code.
@pts Yes, it works but I couldn't explain it clearly before. I updated the post, I hope it better now.
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.
Is it good practice to call scripts from JAVA? Any performance issues?
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();

2 Comments

Is this going to work with Windows as well as Linux?
@ChinmayaB - yes, this is OS agnostic.
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.

Comments

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);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.