You should really look at Process Builder. It is really built for this kind of thing.
ProcessBuilder pb = new ProcessBuilder("myshellScript.sh", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory(new File("myDir"));
Process p = pb.start();
Answer from Milhous on Stack OverflowYou should really look at Process Builder. It is really built for this kind of thing.
ProcessBuilder pb = new ProcessBuilder("myshellScript.sh", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory(new File("myDir"));
Process p = pb.start();
You can use Apache Commons exec library also.
Example :
package testShellScript;
import java.io.IOException;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
public class TestScript {
int iExitValue;
String sCommandString;
public void runScript(String command){
sCommandString = command;
CommandLine oCmdLine = CommandLine.parse(sCommandString);
DefaultExecutor oDefaultExecutor = new DefaultExecutor();
oDefaultExecutor.setExitValue(0);
try {
iExitValue = oDefaultExecutor.execute(oCmdLine);
} catch (ExecuteException e) {
System.err.println("Execution failed.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("permission denied.");
e.printStackTrace();
}
}
public static void main(String args[]){
TestScript testScript = new TestScript();
testScript.runScript("sh /root/Desktop/testScript.sh");
}
}
For further reference, An example is given on Apache Doc also.
Videos
ProcessBuilder pb = new ProcessBuilder("src/lexparser.sh", "myArg1", "myArg2");
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
There are two things that are easy to miss:
Path and CWD. The simplest way to ensure that the executable is found is to provide the absolute path to it, for example
/usr/local/bin/lexparser.shProcess output. You need to read the process output. The output is buffered and if the output buffer gets full the spawned process will hang.
You should use the returned Process to get the result.
Runtime#exec executes the command as a separate process and returns an object of type Process. You should call Process#waitFor so that your program waits until the new process finishes. Then, you can invoke Process.html#getOutputStream() on the returned Process object to inspect the output of the executed command.
An alternative way of creating a process is to use ProcessBuilder.
Process p = new ProcessBuilder("myCommand", "myArg").start();
With a ProcessBuilder, you list the arguments of the command as separate arguments.
See Difference between ProcessBuilder and Runtime.exec() and ProcessBuilder vs Runtime.exec() to learn more about the differences between Runtime#exec and ProcessBuilder#start.
When you execute a script from Java it spawns a new shell where the PATH environment variable is not set.
Setting the PATH env variable using the below code should run your script.
String[] env = {"PATH=/bin:/usr/bin/"};
String cmd = "you complete shell command"; //e.g test.sh -dparam1 -oout.txt
Process process = Runtime.getRuntime().exec(cmd, env);
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);
}
}
With the above test you can not guaranty that whether it is running or not. Because clearly you told that your are running a infinite loop inside your second java application. Now my advise would be to put some System.out.println statement inside that infinite loop and use below java code to execute your shell script. Here in the output.txt file you can see the output from your shell script as well as java program and you will know whether application executed successfully or not. Also put some echo statement inside your shell script as well.
String[] command ={"/root/Desktop/chat/script.sh", "command line param if any"};
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectOutput(new File("/tmp/output.txt"));
String result;
String overall="";
try {
Process p = pb.start();
p.waitFor();
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((result = br.readLine()) != null){
overall = overall + "\n" + result;
}
p.destroy();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
You can't directly execute a .sh script like this, since it's not an executable. Instead, you have to run /bin/sh -c /home/myname/Scrivania/capture.sh instead.
First of all, it's not a good style to work with OS-based features in Java code. Instead of that i suggest you to work with system input/output streams only. For example if your program should handle output of your script, you can do something like:
cat /dev/tty.USB0 > java YourMainClass
and then work directly with System.in.
Even if your program is more complicated than script output consumer, you can rewrite it to remove all OS-based parts from your program, it'll make your code more stable and maintainable.