DJames
DJames

Reputation: 689

Using Java's getRuntime.exec() to Run a Linux Shell Command: How?

Below is a python script that executes a linux bash command "echo Hello World > ./output"

import os

os.system("bash -c \"echo Hello World > ./output\"");

I am trying to do the same with Java. Below is my best effort, following the instructions I found here: Want to invoke a linux shell command from Java

import java.io.IOException;

public class callCommand {
    public static void main(String[] args) {
        try {
            Process p = Runtime.getRuntime().exec(
                new String[]{"bash","-c",
                "\"echo Hello World > ./output\""});
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

It compiles without issue, and runs without complaint, but no output file is generated.

Upvotes: 0

Views: 2626

Answers (2)

Roman
Roman

Reputation: 6656

The extra quotes around echo ... should be removed:

Process p = Runtime.getRuntime().exec(new String[]{
        "bash", "-c",
        "echo Hello World > ./output"
});

The python version needs extra quotes to tell the underlying system that echo Hello World > ./output is a single argument. The java version explicitly specifies arguments as separate strings, so it doesn't need those quotes.

Also, your version doesn't "run without complaint", you just don't see the complaints, because you don't read the error stream of the created process.

Upvotes: 2

Little Santi
Little Santi

Reputation: 8793

The standard input, output and error streams to/from a system process started from Java are accessed through the methods getOutputStream(), getInputStream() and getErrorStream() of Process.

I recommend you to get the error output produced by your system process:

Process p = Runtime.getRuntime().exec(...);
InputStream input=p.getErrorStream();
do 
{
    n=input.read(...);
}
while (n>=0);

Be careful: For your actual problem, this would be enough. But for a process which produces a longer error/output, you need to perform the reading of the standard error/output in a separate thread. If not, the system process would block when the error/output buffer is full, and wait till it is externally consumed, and if you place the reading loop just after the process is executed, it will never execute and so, the program will get into a deadlock.

Upvotes: 1

Related Questions