Capturing stdout when calling Runtime.exec
You need to capture both the std out and std err in the process. You can then write std out to a file/mail or similar.
See this article for more info, and in particular note the StreamGobbler
mechanism that captures stdout/err in separate threads. This is essential to prevent blocking and is the source of numerous errors if you don't do it properly!
Java Runtime.getRuntime(): getting output from executing a command line program
Here is the way to go:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
Read the Javadoc for more details here. ProcessBuilder
would be a good choice to use.
Runtime's exec() method is not redirecting the output
You need to use ProcessBuilder
to redirect.
ProcessBuilder builder = new ProcessBuilder("sh", "somescript.sh");
builder.redirectOutput(new File("out.txt"));
builder.redirectError(new File("out.txt"));
Process p = builder.start(); // may throw IOException
Redirect Runtime.getRuntime().exec() output with System.setOut();
The standard output of Runtime.exec is not automatically sent to the standard output of the caller.
Something like this aught to do - get access to the standard output of the forked process, read it and then write it out. Note that the output from the forked process is availble to the parent using the getInputStream()
method of the Process instance.
public static void main(String[] args) throws Exception {
System.setOut(new PrintStream(new FileOutputStream("test.txt")));
System.out.println("HelloWorld1");
try {
String line;
Process p = Runtime.getRuntime().exec( "echo HelloWorld2" );
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()) );
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (Exception e) {
// ...
}
}
Android: How to process output of Runtime.getRuntime().exec() calling dumpsys on rooted phone
The first thing you should do is to log the stderr
stream that is available for your process as well. This will give you information about what is wrong with your command.
Your command is not correctly processed as it is seen as one command. The reason is explained in this answer.
The solution is to use a String[]
as an argument of exec
and explicitly execute the command with the shell. I wrote some code that executes your command, but it is in Java on an unrooted device. Still, it generates output and grep works.
String[] arrayCommand = {"sh", "-c","dumpsys telephony.registry | grep \"permission\""};
Runtime r = Runtime.getRuntime();
Process process = r.exec(arrayCommand);
String stdoutString = convertInputStreamToString(process.getInputStream());
String stderrString = convertInputStreamToString(process.getErrorStream());
Java Process: read stdout and stderr of a subprocess in a single thread
No, you can't just create a SelectableChannel
from the InputStream
returned by a Process
, this is a Java api limitation AFAICT.
Efficient execution and output stream redirection of process spawned with Runtime.exec()
The fastest way for your task is to use Java 7 and
return new ProcessBuilder(cmdarray).inheritIO().start().waitFor();
If that doesn’t help, I think there’s nothing you can do as every other approach would add even more code to your runtime environment that has to be processed.
I want realtime output of my Runtime.getRuntime().exec()
The issue you describe is most likely caused by the application you called: many applications use unbuffered I/O when connected to a terminal, but bufferen I/O when connected to a pipe. So your cmd
may simply decide not to write its output in small bits, but instead in huge chunks. The proper fix is to adjust the command, to flush its output at the appropriate times. There is little you can do about this on the Java side. See also this answer.
Java Runtime.getRuntime().exec unable to catch all output
That is because you are only capturing standard output from Process#getInputStream
(like System.out
) and errors are printed in error stream (System.err
). You will have to capture Process#getErrorStream()
as well.
Instead of Runtime.exec()
you can use ProcessBuilder
and then invoke redirectErrorStream
on it to merge those 2 streams.
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#redirectErrorStream()
Related Topics
How to Convert from Int to String
Why Does the Foreach Statement Not Change the Element Value
How to Format the Day of the Month to Say "11Th", "21St" or "23Rd" (Ordinal Indicator)
Difference Between Javac and the Eclipse Compiler
How to Run Test Methods in Specific Order in Junit4
How to Programmatically Determine Operating System in Java
How to Find the User'S Home Directory in Java
What Does "Possible Lossy Conversion" Mean and How to Fix It
Java 8 List≪V≫ into Map≪K, V≫
How to Use Wait and Notify in Java Without Illegalmonitorstateexception
How to Sort by Two Fields in Java