How to Run Unix Shell Script from Java Code

Running a shell script from java code

Your code is right and I am sure you are not getting exceptions, if you read using proc.getErrorStream() you will not get anything.

Commands 100% get executed that way, having said that now thing is that you are echo'ing something and you need to read it back using BufferedReader.

Check below example which will successfully create a directory called "stackOverflow" and print what you are echo'ing. For the putting it into a log file I am afraid that you can do it using ">", you may have to use some editor command or create file using Java.

Bottom line: Runtime.getRuntime().exec("command") is the correct and defined way to execute Unix commands or scripts from Java and it WORKS.

test.sh

#!/bin/bash
echo "hola"
mkdir stackOverflow

Test.java

import java.io.*;
public class Test {

public static void main(String[] args) throws Exception {
try {
String target = new String("/home/hagrawal/test.sh");
// String target = new String("mkdir stackOver");
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(target);
proc.waitFor();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println("### " + output);
} catch (Throwable t) {
t.printStackTrace();
}
}
}

Run shell script from java code

Another way of doing would be to use Runtime.getRuntime(). Something like this

  public void executeScript() throws IOException, InterruptedException {
Process p = Runtime.getRuntime().exec("sh /root/Desktop/chat/script.sh");
p.waitFor();

BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(p.getErrorStream()));


String line = "";
while ((line = reader.readLine()) != null) {
System.out.println(line);
}

line = "";
while ((line = errorReader.readLine()) != null) {
System.out.println(line);
}
}

Running Unix shell script from Java code, and dealing with prompts

The stdin of the exec'd process can be accessed through proc.getOutputStream()
Everything you send through this stream will be delivered to the ssh-keygen process through its stdin.

Of course, if you don't send the kind of input it's expecting, the process may just return some warning message and keep on waiting. What you need to send will be very dependent on the process you're sending it to.

Also: You're processing ssh-keygen's output by reading the InputStream and Error Stream. However, you'll likely want to do this in a separate thread - the way you have it now, if the process writes too much to stderr before writing to stdout, it may hang because of a full buffer...

Execute shell script in Java and read Output

The primary reason why this doesn't work is that `$2` is not the same as `ls -1 | tail -1`, even when $2 is set to that string.

If your script accepts a literal string with a command to execute, you can use eval to do so.

I created a complete example. Please copy-paste it and verify that it works before you try applying any of it to your own code. Here's Test.java:

import java.io.*;                                                            

public class Test {
public static void main(String[] args) throws Exception {
String[] command = { "./myscript", "key", "ls -t | tail -n 1" };
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String s;
while ((s = reader.readLine()) != null) {
System.out.println("Script output: " + s);
}
}
}

And myscript:

#!/bin/bash                                
key="$1"
value=$(eval "$2")
echo "The command $2 evaluated to: $value"

Here's how we can run myscript separately:

$ ls -t | tail -n 1
Templates

$ ./myscript foo 'ls -t | tail -n 1'
The command ls -t | tail -n 1 evaluated to: Templates

And here's the result of running the Java code:

$ javac Test.java && java Test
Script output: The command ls -t | tail -n 1 evaluated to: Templates

Executing shell script from java code and check if execution has passed

You need to check if the process terminated which you can do with Process.waitFor() which blocks until the process completed. The return value of this call is the return code of the system command you invoked.

How to run Unix shell script in a java code using ExpectJ tool?

In your Java code you look for

s.expect("VALID_NAME=");

yet in your Bash code, you have:

echo "Name: "

It seems like simply changing your Java code to the following should work:

s.expect("Name: ");


Related Topics



Leave a reply



Submit