I'm trying to launch a process in java, read the output, write to the program, then read what it responds with. From all the other answers on SO, this is what I have come up with:
class Main
{
public static void main(String[] args) {
String line = "";
try {
ProcessBuilder pb = new ProcessBuilder("C:\\myProgram.exe");
Process p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
output.write("foo");
output.newLine();
output.flush();
while ((line = input.readLine()) != null) {
System.out.println(line);
}
p.destroy();
}
catch (IOException e){
}
}
}
It launches the program, and gives me the output just as expected.
When i write foo, I expect the program to come back with another response, but it never does.
What am I doing wrong?
Related
I'm performing the following code to execute linux commands in my android application that I'm creating:
public void RunAsRoot(String[] cmds){
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
}
I want to know if there is a way to know what the command is returning after it is executing. for example, if I do "ls" I would like to see what the command wold normally output.
try this code :
try {
Process process = Runtime.getRuntime().exec("ls");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder result=new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result.append(line);
}
TextView tv = (TextView)findViewById(R.id.textView1);
tv.setText(result.toString());
}
catch (IOException e) {}
Let's go by a "String function" example
String shell_exec(String s)
{
String line="",output="";
try
{
Process p=Runtime.getRuntime().exec(new String[]{"sh","-c",s});
BufferedReader b=new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line=b.readLine())!=null){output+=line+"\r\n";}
}catch(Exception e){return "error";}
return output;
}
Now just use it:
String s=shell_exec("ls /data/data/com.mycompany.myapp");
package online_test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class cmdline_test {
/**
* #param args
*/
public static void main(String[] args) {
try {
String[] command = new String[3];
command[0] = "cmd";
command[1] = "/c";
command[2] = "c: && dir && cd snap";
Process p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
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);
}
while ((Error = stdInput.readLine()) != null) {
System.out.println(Error);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
When I run this code, I get the output of this code printed to the console. However, I wasn't able to figure out how to copy that output to a file. How would I go about doing so?
Use a ProcessBuilder:
final File outputFile = Paths.get("somefile.txt").toFile();
final ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "whatever")
.redirectOutput(outputFile)
.redirectErrorStream(true);
final Process p = pb.start();
// etc
Read the javadoc carefully; there is a lot more you can do with it (affecting the environment, changing the working directory etc).
Also, do you really need to go through an interpreter at all?
A more simple solution is to change the outputstream of System.out to a file. This way, every time you invoke System.out.println(...) it will write to said file. Add this to the start of your program:
File file =
new File("somefile.log");
PrintStream printStream = null;
try {
printStream = new PrintStream(new FileOutputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.setOut(printStream);
You can do the same for System.err for printing errors to a different file.
everyone, I have a process that needs to get standard output and log/error/exception output from the subprocess. The standard output is fine, but I can't get ErrorStream, therefore the program is stuck there because of that. Here is my simple code. There is nothing magic, but why can't I get the error stream here? Thanks for looking at it.
BufferedReader standard =
new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader error =
new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = standard.readLine()) != null) {
System.out.println(line);
}
while ((line = error.readLine()) != null) {
System.out.println(line);
}
Now, as suggested, i used two threads to process the output and error streams, but still had the same problem, as follows. Can anybody give me some insights? Thanks.
ProcessBuilder pb = new ProcessBuilder(listArgs);
pb.redirectErrorStream();
Process process = pb.start();
StreamThread output = new StreamThread(process.getInputStream());
StreamThread error = new StreamThread(process.getErrorStream());
output.start();
error.start();
while (true) {
try {
output.join();
break;
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
The definition of the StreamThread:
public static class StreamThread extends Thread{
private InputStream input = null;
public StreamThread(InputStream in){
input = in;
}
String line = null;
public void start(){
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
try{
while( (line=reader.readLine()) != null ){
System.out.println(line);
}
reader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
Look at your loops:
while ((line = standard.readLine()) != null) {
System.out.println(line);
}
while ((line = error.readLine()) != null) {
System.out.println(line);
}
You're going to keep reading from the output stream until it's finished - which is likely to be when the process terminates. Only then do you start reading the error stream.
You should probably put at least one of these into a different thread, so you can read from both streams at the same time.
I'm writing a Java program that is used to call a PHP script in set intervals. The PHP script outputs a lot of data, and it is the client's requirement that the Java program displays all the PHP script's output while the script runs.
The method I'm using is:
Runtime.getRuntime().exec(new String[]{"php", "file.php"});
Then using an InputStreamReader to grab output, primarily using examples from here. The problem I'm having is that the stream reader only outputs the data once the PHP script exits (which makes sense considering how the output is looped through).
How would I go about printing the script's output live while the script is running?
I did this by reading the output from a separate thread:
Process p = Runtime.getRuntime().exec(commands);
final InputStream stream = p.getInputStream();
new Thread(new Runnable() {
public void run() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(stream));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
// TODO
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// ignore
}
}
}
}
}).start();
For now I decided to go with Andrew Thompson's suggestion:
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();
InputStreamReader istream = new InputStreamReader(process.getInputStream());
BufferedReader br = new BufferedReader(istream);
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
process.waitFor();
This is still not what I'm looking for though, so for now I'm leaving the question unanswered.
I trying to run multiple command shells from Java. I am able to do that (and get the output in the console using PrintWriter). However, I want to be able to get the output of each command in a separate String. Is that possible?
Here is a part of the code :
File wd = new File("/bin");
Process proc = null;
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
out.println("cd ..");
out.println("ls");
System.out.println("moving to /var directory");
out.println("cd /var/");
out.println("ls");
//get output of ls command in string variable
out.println("cd ..");
out.println("cd /etc/");
out.println("ls -a");
out.println("ps");
out.println("exit");
try {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
proc.waitFor();
in.close();
out.close();
proc.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
Have you tried putting a section like
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = in.readLine()) != null) {
builder.append(line).append("\n");
}
String commandOutput = builder.toString();
after each command? Is that roughly what you are trying to achieve?