multiple command in process builder - java

How can I give multiple command in process builder.
Basically my first command is to enter in nusmv interface then further commands are nusmv commands to create xml file but my program is not working after first command, it is not taking further commands.
String[][] commands = {
{"nusmv", "-int", "D:/files/bitshift.smv"},
{"go"},
{"process_model"},
{"show_traces","-p","4","-o","D:output.xml"}};
for (String[] str : commands) {
ProcessBuilder pb = new ProcessBuilder(str);
pb.redirectErrorStream(true);
Process process = pb.start();
InputStream is = process.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
System.out.println(inputLine);
}
System.err.println("next one");
}

You need to brush up your understanding of the process model, and read the ProcessBuilder documentation in light of that.
What your code does is, create a process to run the command "nusmv -int D:/files/bitshift.smv", then create a new process to (try to) run the command "go", and so on. Clearly that is not what you want.
You want one process; you want it to run "nusmv", and you want to write commands to its input. Assuming that "nusmv" reads commands from stdin in a conventional way, you should be able to do something like:
ProcessBuilder pb = new ProcessBuilder("numv","-int","D:/files/bitshift.smv");
Process process = pb.start();
// Write commands
PrintWriter commands = new PrintWriter(process.getOutputStream());
commands.println("go");
commands.println("processmodel");
commands.println("show_traces -p 4 -o D:output.xml");
commands.close();
// Read from process.getInputStream(), process.waitFor(), process.exitValue()
...

Related

Java Execute an external program and capture the output

So i try to Execute an external program and capture the output.
Currently the part that execute command works fine (using .bat file) and i can see the output on the cmd window.
The part that need to read the output not and it seemt that it stack inside my while
This is what i have try:
String[] command = {"cmd.exe", "/C", "Start", "d:\\batFile.bat"};
Process process = Runtime.getRuntime().exec(command);
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
Update
This is my .bat file:
docker volume create --name=mydb
timeout 3
docker run -d -p 27017:27017 -v mydb:/data/db mongo
timeout 3
Maybe you can try to redirect the output like this :
Process runtimeProcess1;
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C","Start","d:\\batFile.bat");
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
pb.redirectInput(Redirect.INHERIT);
runtimeProcess1 = pb.start();
int processComplete1 = runtimeProcess1.waitFor();

Executing custom Commands in Java

With this, we can execute "build in" commands in java. However if we want to run some custom commands from this, Changing "pwd" to "device_id -l" doesn't work. "device_id -l" should list all the ids of attached devices of currently host. if "device_id -l" is executed in terminal itself. it works fine. There is not a question for the "build in" bash commands. Thank you.
String cmd = "pwd";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(cmd);
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null)
System.out.println(line);
We can excuate
You can try using ProcessBuilder.
// create process
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "device_id", "-l");
// start process
Process p = pb.start();
// wait for process exit
p.waitFor();
// read process output
BufferedReader buf = new BufferedReader(newInputStreamReader(p.getInputStream()));
String line = "";
while ((line=buf.readLine())!=null)
System.out.println(line);
You need to split your command+arguments to a String array. In your case, if you want to execute "device_id -l", split that into an array like this:
String[] cmd = new String[] {"/full/path/to/device_id", "-l"};
Process pr = Runtime.getRuntime().exec(cmd);
And, you might want to use ProcessBuilder.
String[] cmd = new String[] {"/full/path/to/device_id", "-l"};
ProcessBuilder pb = new ProcessBuilder(cmd);
Process pr = pb.start();
Finally, you'll have to take into account that Java does not look for executables in PATH (like command shell does), you'll have to provide full path to the executable/script that you want to execute (or it has to be in the working directory; you can set the working directory with ProcessBuilder.directory(File)).
See also: Difference between ProcessBuilder and Runtime.exec()

Opening and closing application from Java

I'm trying to use ProcessBuilder to start application in cmd.exe, wait for it to finish and then close it. So far I tried:
String[] cmdline=new Stirng{}("cmd.exe","/C","start",application_and_parameters);
ProcessBuilder processBuilder = new ProcessBuilder(cmdline);
Process p = processBuilder.start();
//get error and input streams
int exitVal = p.waitFor();
It opens window as expected, but doesn't close. I tried:
p.destroy()
and to send exit command:
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writer.write("exit");
writer.flush();
but without success, cmd stays. Could anyone suggest a solution?
Remove start , It will execute your process directly without opening command prompt so you will not need to close it manually.Below is you code snippet as an example
String[] cmdline=new String[]{"cmd.exe","/C","notepad.exe"};
ProcessBuilder processBuilder = new ProcessBuilder(cmdline);
Process p = processBuilder.start();
//get error and input streams
int exitVal = p.waitFor();
System.out.println(exitVal);

How to execute terminal command in specific directory from java

I am trying to execute originate command in specific directory "/usr/local/freeswitch/bin", In bin I have to run executable file fs_cli by ./fs_cli command, In fs_cli I have to execute following command
originate loopback/1234/default &bridge(sofia/internal/1789)
Its working fine from terminal, The same command can be executed from bin
./fs_cli -x "originate loopback/1234/default &bridge(sofia/internal/1789)"
I tried folowing java program to do the above task
Process pr = Runtime.getRuntime().exec("./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)\"");
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
I have creted symbolic link of fs_cli and placed in current location
The above program is showing following output
Output
-ERR "originate Command not found!
As far as I am concerned whwn above command is working fine with terminal it should be the same from java, So it shows I am wrong somewhere
Please help me to sort out this problem.
Use ProcessBuilder and supply a directory path
ProcessBuilder pb = new ProcessBuilder(
"./fs_cli",
"-x",
"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)");
pb.directory(new File("..."));
Process pr = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
Where possible, you should provide the command arguments as separate Strings, this will pass each as a separate argument to the process and take care of those arguments that need to be escaped by quotes for you (unless it's expecting the quotes, then you should include them anyway)
The other way is:
ProcessBuilder processBuilder = new ProcessBuilder( "/bin/bash", "-c", "cd /usr/local/freeswitch/bin && ./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789)\"" );
processBuilder.start();

How to perform a shell redirection (command > output.txt) using ProcessBuilder?

I wanted to backup a MySQL database using ProcessBuilder and the > character is not being interpreted as I expected. This is my code:
java.util.List<String> cmd = new java.util.ArrayList<>();
cmd.add("mysqldump");
cmd.add("-u");
cmd.add("root");
cmd.add("-p"+password);
cmd.add("DBx");
cmd.add(">");
cmd.add("DBbk.sql");
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File("."));
Process p = pb.start();
p.waitFor();
BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while((line = err.readLine()) != null) {
System.out.println(line);
}
The output is:
Warning: Using a password on the command line interface can be insecure.
mysqldump: Couldn't find table: ">"
The process builder is executing the program directly, not executing it through a shell/command prompt. Therefore, you don't get any nice features of the shell like the > character for redirection. Sorry.
Give this a try (just displaying the significant portion of the solution):
new ProcessBuilder("cmd", "/C", "your_command > DBbk.sql").start()
This way you're explicitly calling cmd. In Linux you could call bash or whatever shell you use.

Categories