ubercordes
ubercordes

Reputation: 3

How to execute commands in a command-line application through Runtime.getRuntime().exec()

I am trying to execute a third-party command-line application from Java. The application is called CWB. I'm using the following code:

process = Runtime.getRuntime().exec(script.sh);

LinkedList<String> stringList = new LinkedList<String>();

BufferedReader reader = new BufferedReader(
    new InputStreamReader(process.getInputStream()));

String line = "";

while ((line = reader.readLine()) != null) {
    stringList.add(line);
}

int exitVal = 0;

exitVal = process.waitFor();
if (exitVal == 0) {
    // Success
    return stringList;
} else {
    // Failure
    return null;
}

The commands are put in a file script.sh (I'm in Linux). The script contains the following two commands:

# Run CWB application from Terminal
./cwb-nc-ccs-x86-linux.bin
# Execute a CWB-specific command
load file_name.ccs

The behavior is different when I execute CWB from the terminal and when I execute it in Java through Runtime.getRuntime().exec(). When I execute CWB from Terminal, I obtain this output:

CWB_output_from_terminal

But, when I execute from Java through Runtime.getRuntime().exec(), I obtain this output in the console:

The Concurrency Workbench of the New Century
(Version 1.2 --- June, 2000)

That is, the shell in Java stops execution after the command ./cwb-nc-ccs-x86-linux.bin. I think the reason is that, when I start the CWB process, it's like as if I enter in a new "environment". It can be noticed because the cursor line where I type the commands starts with cwb-nc>, as we can see in the picture above. Thus, being in a new "environment" and not in the shell, Java doesn't know how to pass commands to this environment. Am I right? How can I solve this problem and execute the other command in the script (load file_name.ccs)?

Upvotes: 0

Views: 1319

Answers (2)

that other guy
that other guy

Reputation: 123650

If you had tried to run your script outside of Java, you'd see that it doesn't work there either. You should focus on writing a script that works first, and only try invoking it from Java when it does.

The problem with the script is detailed here: Pass commands as input to another command (su, ssh, sh, etc).

However, since you're running from Java, you could and probably should implement this purely in Java without a shell script:

process = Runtime.getRuntime().exec(new String[] { "./cwb-nc-ccs-x86-linux.bin" });
PrintStream writer = new PrintStream(process.getOutputStream());
writer.println("load file_name.ccs");
writer.close();
...

Upvotes: 0

MrsNickalo
MrsNickalo

Reputation: 217

I actually had a similar problem when using Lilypond in my Java Application. I believe you are accurate in your conclusion about how the Java command works. It is not equivalent to typing in the command shell, so there are some special preparations we have to make in order to get it to do what we want.

I had to create a script file and then fool around with the execute command until I found one that actually brought up the command window and executed the commands correctly:

//Run the script
            String command = "cmd.exe /C \"C:/Users/Lindsay Gen10/Documents/NetBeansProjects/capstone/src/main/resources/templates/pdfs/" 
                    + song.getTitle().replaceAll(" ", "") + "Script.sh\"";
            Runtime.getRuntime().exec("cmd /c run cmd.exe /K ");
            Process p = Runtime.getRuntime().exec(command);
            p.waitFor();

By using the cmd /c run, it actually forces a command window to open. I'm not 100% sure this will solve your problem too, but it's worth a try!

Upvotes: 1

Related Questions