One option is to handle ~ yourself:
CopyString homeDir = System.getenv("HOME");
String[] cmd = { homeDir + "/path/to/shellscript.sh", "foo", "bar" };
Process p = Runtime.getRuntime().exec(cmd);
Another is to let Bash handle it for you:
CopyString[] cmd = { "bash", "-c", "~/path/to/shellscript.sh foo bar" };
Process p = Runtime.getRuntime().exec(cmd);
Answer from ruakh on Stack OverflowOne option is to handle ~ yourself:
CopyString homeDir = System.getenv("HOME");
String[] cmd = { homeDir + "/path/to/shellscript.sh", "foo", "bar" };
Process p = Runtime.getRuntime().exec(cmd);
Another is to let Bash handle it for you:
CopyString[] cmd = { "bash", "-c", "~/path/to/shellscript.sh foo bar" };
Process p = Runtime.getRuntime().exec(cmd);
As already mentioned, tilde is a shell-specific expansion which should be handled manually by replacing it with the home directory of the current user (e.g with $HOME if defined).
Besides the solutions already given, you might also consider using commons-io and commons-exec from the Apache Commons project:
Copy...
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import org.apache.commons.io.FileUtils;
...
CommandLine cmd = new CommandLine("path/to/shellscript.sh");
cmd.addArgument("foo");
cmd.addArgument("bar");
Executor exec = new DefaultExecutor();
exec.setWorkingDirectory(FileUtils.getUserDirectory());
exec.execute(cmd);
...
Use ProcessBuilder , it's what it's designed for, to make your life easier
ProcessBuilder pb = new ProcessBuilder("test.sh", "/path", "/my/text file");
Process p = pb.start();
To recreate the command you run in shell manually, test.sh "/path to/my/text file", you will need to include the quotes.
final StringBuilder sb = new StringBuilder("test.sh");
sb.append(" \"/path to/my/text file\""); //notice escaped quotes
final Process p = Runtime.getRuntime().exec(sb.toString());
Videos
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();
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.
This is a simple code to execute the shell script and read its output:
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
String[] command = { "./flows.sh", "suspend" };
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); // Replace this line with the code to print the result to file
}
}
}
To print it to a file, just replace the System.out.println for the code to write into a file
You can use the JSCH API:
http://www.jcraft.com/jsch/examples/Shell.java.html http://www.jcraft.com/jsch/examples/Exec.java.html
Bye!
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);
You can try this:
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh --ip=abc.txt --seqs=20");
Process script_exec = pb2.start();
OutputStream in = script_exec.getOutputStream();
in.write("abc".getBytes());
in.write("1".getBytes());
in.write("10".getBytes());
in.flush();
in.close();
This code writes abc, 1 and 10 to process input.
I recommend to use Apache Commons Exec, it helps to run external processes in multi-platform environment.
Here is the tutorial: http://commons.apache.org/proper/commons-exec/tutorial.html