I'm running my processes like this:
builder = new ProcessBuilder("/bin/bash", "-c", "./MessageGenerator | ./SimpleEchoServer");
process = builder.start();
Then process.destroy() or forciblyDestroy() doesn't work. Is it because I'm using a pipe? How can I kill these processes?
you should also split up the pipe command. I've written a little example:
package com.company;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder processBuilder;
String line;
processBuilder = new ProcessBuilder("/bin/bash", "-c", "ls -l", "|", "grep java");
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println ("Stdout: " + line);
}
Thread.sleep(10000);
process.destroy();
}
}
Related
I want to execute a command from Java but this command wants me to give it a username.
Like this example:
$ my command
[command] Username:_
So how can I give the command my username in Java?
Currently my code is like this:
Process p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s;
while ((s = br.readLine()) != null){
System.out.println(s);
}
br.close();
p.waitFor();
p.destroy();
You need to create another thread and pump user input through process#getOutputStream(). See the following example:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class ProcessWithInput {
public static void main(String[] args) throws IOException, InterruptedException {
Process p = Runtime.getRuntime().exec("cat");
OutputStream os = p.getOutputStream();
os.write("Hello World".getBytes());
os.close();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);
}
br.close();
p.waitFor();
p.destroy();
}
}
Ofcourse, you need to do proper error/exception handling etc.
Other option is to use ProcessBuilder which allows you to provide input through a File.
I just conducted simple test code for Java Process Builder.
There are 4 examples and everything is working smoothly excluding last one.
Here is my codes
public class bashProcessor {
public static void main(String args[]) {
try {
ProcessBuilder pb;
pb = new ProcessBuilder("/bin/bash", "-c", "touch Jin_1.sh");
pb.start();
pb = new ProcessBuilder("/bin/bash", "-c", "mkdir Jin_2");
pb.start();
pb = new ProcessBuilder("/bin/bash", "-c", "bash /home/Jin/test.sh");
pb.start();
//below is not working
pb = new ProcessBuilder("/bin/bash", "-c",
"bash /home/solr-tomcat/bin/shutdown.sh warm4 solr-instances");
pb.start();
System.out.println("pb job is done now");
Thread.sleep(3000);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
When I type last example(bash /home/solr...) by hand-typing. It works without any error. I need your kind help. if you have any idea
please let me know it would be great help.
As pointed out by #ug_ try to remove bash from command and then execute your code. Following code works fine with multiple command.
cmd.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class cmd {
public static void main(String[] args) {
try {
String[] command = new String[3];
command[0] = "/bin/bash";
command[1] = "-c";
command[2] = "javac -verbose HelloWorld.java";
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String Error;
while ((Error = stdError.readLine()) != null) {
System.out.println(Error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
I'm running ffmpeg command to generate video for given images (img001.jpg, img002.jpg ...) it's creating slide.mp4, but it waits infinitely:
public class Ffmpeg {
public static void main(String[] args) throws IOException, InterruptedException {
String path = "E:\\pics\\Santhosh\\FadeOut\\testing";
String cmd = "ffmpeg -r 1/5 -i img%03d.jpg -c:v libx264 -r 30 -y -pix_fmt yuv420p slide.mp4";
runScript (path, cmd);
}
private static boolean runScript(String path, String cmd) throws IOException, InterruptedException {
List<String> commands = new ArrayList<String>();
commands.add("cmd");
commands.add("/c");
commands.add(cmd);
ProcessBuilder pb = new ProcessBuilder(commands);
pb.directory(new File(path));
pb.redirectErrorStream(true);
Process process = pb.start();
flushInputStreamReader(process);
int exitCode = process.waitFor();
return exitCode == 0;
}
}
private static void flushInputStreamReader (Process process) throws IOException, InterruptedException {
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line=null;
StringBuilder s = new StringBuilder();
while((line=input.readLine()) != null) {
s.append(line);
}
}
Any suggestions?
After writing the function flushInputStreamReader, its working
Aside from reading the ErrorStream, there's a better way to handle this.
Add -loglevel quiet to the command, so that the ErrorStream won't overflow and blocking the process at the first place.
Here the working code for the live project:
public void executeHLS() throws IOException, InterruptedException {
String original_video_file = "C:\\xampp\\htdocs\\hls\\test.mp4";
String conversion = "cmd.exe /c F:\\java\\ffmpeg\\ffmpeg\\bin\\ffmpeg -i "+original_video_file+" -hls_time 10 -hls_playlist_type vod -hls_segment_filename \"C:\\xampp\\htdocs\\hls\\video_segments_%0d.ts\" C:\\xampp\\htdocs\\hls\\hls_master_for_test.m3u8";
//String conversion = "cmd.exe /c "+"dir";
String[] cmds={conversion};
for(int i=0;i<cmds.length;i++) {
try {
System.out.println(cmds[i]);
if(runScript(conversion)) {
System.out.println("Operation Successfull!!!!");
}else {
System.out.println("Operation Failed ####");
}
} catch (IOException e) {
e.printStackTrace();
}
//System.exit(0);
}
}
private static boolean runScript(String cmd) throws IOException, InterruptedException {
ArrayList<String> commands = new ArrayList<String>();
commands.add("cmd");
commands.add("/c");
commands.add(cmd);
ProcessBuilder pb = new ProcessBuilder(commands);
//pb.directory(new File(path));
pb.redirectErrorStream(true);
Process process = pb.start();
flushInputStreamReader(process);
int exitCode = process.waitFor();
return exitCode == 0;
}
private static void flushInputStreamReader (Process process) throws IOException, InterruptedException {
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line=null;
StringBuilder s = new StringBuilder();
while((line=input.readLine()) != null) {
s.append(line);
}
}
I'm currently doing an Eclipse plugin mainly calling various scripts and interact with the return values.
my main problem is the ProcessBuilder. If I e.g. call a script that's creating a new Visual Basic window I'm not able to interact with the plugin anymore till I close the VB window. Seems that the cmd command is still running in the background and only after it stops the plugin responds again.
how am I able to fix it? should it run asynchronous in any way?
this is the ProcessBuilder I'm using:
public void execute(String scriptCMD) {
try {
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c",
scriptCMD);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader r = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) {break;}
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Here's a simple example of execution of the process asynchronously in another thread. I've used the single thread executor because there's only one task executed:
java.util.concurrent.Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c",
scriptCMD);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader r = new BufferedReader(new InputStreamReader(
p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) {break;}
System.out.println(line);
}
}
});
I know this question has been asked before but those answers didn't provide me an answer.
I want to execute a exec jar file in my java program and get the output from executing jar into a string. Here below are the codes I have used so far without success.
cmdlink = "java -jar iwtest-mac.jar"+" "+cmd;
System.out.println(cmdlink);
Process process = Runtime.getRuntime().exec(cmdlink);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {
st = reader.readLine();
}
process.waitFor();
and another code I have tried is as follows:
String cmdlink = "iwtest-mac.jar "+cmd;
ProcessBuilder pb = new ProcessBuilder("java", "-jar", cmdlink); //cmd here is a string that contains inline arguments for jar.
pb.redirectErrorStream(true);
pb.directory(new File("C:\\Users\\Dharma"));
System.out.println("Directory: " + pb.directory().getAbsolutePath());
Process p = pb.start();
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
for (String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println( line );
p.waitFor();
Both of the above are not working for me. Any suggestions are appreciated.
This works For Me..
public class JarRunner {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "C:\\JCcc.jar");
pb.directory(new File("C:\\"));
try {
Process p = pb.start();
LogStreamReader lsr = new LogStreamReader(p.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class LogStreamReader implements Runnable {
private BufferedReader reader;
public LogStreamReader(InputStream is) {
this.reader = new BufferedReader(new InputStreamReader(is));
}
public void run() {
try {
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is what the Docs says-
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
You can pass any number of arguments in constructor.
Read more about process builder here.