I am running a script in a java program using:
Runtime.getRuntime().exec()
I am able to open the terminal application using this.
If I give command to run the script. It's happening but I am not able to get the logs in the terminal. I am using MAC. I want to get the logs in the terminal.
You can use a Process variable to get what return from that command, and use method such as: getInputStream(), getOutputStream(), getErrorStream(). Example:
Process p = null;
try {
p = Runtime.getRuntime().exec(....your stuff here)
p.getOutputStream().close(); // close stdin of child
InputStream processStdOutput = p.getInputStream();
Reader r = new InputStreamReader(processStdOutput);
BufferedReader br = new BufferedReader(r);
String line;
while ((line = br.readLine()) != null) {
//System.out.println(line); // the output is here
}
p.waitFor();
}
catch (InterruptedException e) {
...
}
catch (IOException e){
...
}
finally{
if (p != null)
p.destroy();
}
The Process object returned by the method call above has an getInputStream() method (as well as ones for the error and output streams). You have to read from those if you want to grap the inputs and outputs of your script.
For reference: http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html
in terminal, using > to output the log to file. For example: ls / > rootfolder.txt
Using that way, you can output the log to file and then read the log from the file.
Related
Basically, I have a problem which is, I am using ProcessBuilder () to run Noxim simulator from java IDE, but neither the shell opened nor the results returned. It just displayed this error :
Exit with error code: 127
I tried the same code to execute the ping command, and it worked and returned the output shown in the shell. I also used the code run Kdeveloper and it worked well.
Note: the path is correct as It worked well in the shell
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/home/sa/Bureau/NOXIM/noxim/bin/noxim");
try {
Process process = processBuilder.start();
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
It's important to read the error stream too. I guess you see some more messages. Have a look here: https://gist.github.com/th-schwarz/041e13ede396a869c7681b5ad637460c
The easiest way is to read the error stream too is:
processBuilder.redirectErrorStream(true);
We can use Jython to implement python in java, but I dont want to go for that approach, what I am looking for is using command line utility and fire python command to execute the code and get the console output in java code.
python Main.py < input.txt
I used above command in terminal, it works there, giving me output, but unable to get the output in java code.
Note: Main.py and input.txt and java code in the same folder
What I am doing wrong in java code?
Here is Sample java code which I am calling in order to execute external python code
try {
Process process = Runtime.getRuntime()
.exec("python Main.py < input.txt");
process.waitFor();
System.out.println(process);
StringBuilder output
= new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
System.out.println("here");
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
} else {
System.out.println("Process failed");
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
Here is a sample python code:
x = input();
y = input();
print(type(x));
print(type(y));
print(x + y);
here is a sample input file which I am passing as a input to the python code
30
40
As sandip showed, executing a command in java is not the same as running commands through BASH.
At first I tried to execute
bash -c "python Main.py < input.txt" (through java).
For some reason this didn't work, and even if it did its not a great solution as its dependent on the system its running on.
The solution I found to work was by using ProcessBuilder to first make the command, and redirect its input to a file. This allows you to keep the python code unchanged, and for me at least, give the same result as just running the BASH command.
Example:
ProcessBuilder pb = new ProcessBuilder("python3","Main.py");
//Make sure to split up the command and the arguments, this includes options
//I only have python3 on my system, but that shouldn't affect anything
pb.redirectInput(new File("./input.txt"));
System.out.println(pb.command());
Process process = pb.start();
//The rest is the exact same as the code in the question
Heres the ProcessBuilder docs for quick reference
java process not accept < symbol to input file in python command.
Instead you can run like this
python file
f = open("input.txt", "r")
for x in f:
print(type(x));
print(x)
java file
Process process = Runtime.getRuntime().exec("python Main.py input.txt");
process.waitFor();
System.out.println(process);
StringBuilder output
= new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
System.out.println("here");
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("Success!");
System.out.println(output);
} else {
System.out.println("Process failed");
}
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
and use and same text file.
It should print in console
I'm wrapping command line application that I oftenly use with GUI interface. It basically comes down to executing it (as Java process) and then parsing its responses. However one of the usecases requires to take additional action by enduser (application asks if user wants to overwrite a file) and I'm not sure how to handle that. Both InputStream and ErrorStream freezes as soon as this prompt comes up. Here is a (pretty generic) code of executeCommand method:
private void executeCommand(String command) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("bash", "-c", command);
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = reader.readLine()) != null) {
//some actions "File already exists. Do you want to overwrite ? [y/N]" line never gets to this point
}
while ((line = errorReader.readLine()) != null) {
//some actions "File already exists. Do you want to overwrite ? [y/N]" line never gets to this point
}
handleExitCode(process.waitFor(),"Success!");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
I assume that "File already exists. Do you want to overwrite ? [y/N]" prompt is being passed through some other channel. I just don't know how to handle it. The ideal scenario for me would be if I could prompt messageBox with the same question and then pass the response accordingly.
When you are forking a child process, it needs to inherit I/O from parent process to talk stdin and stdout. Use ProcessBuilder.inheritIO to redirect your command streams in your stdin, stdout and stderr.
I'm using UBUNTU/LINUX
I'm trying to build swing application for myself(this app need to work other platforms too) and i can not execute some commands on java.I tried to execute "java -version"
Here is my code:
Runtime run = Runtime.getRuntime();
Process p = run.exec("java -version");
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
for (String output = br.readLine(); output != null; output = br.readLine()) {
System.out.println(output);
}
} catch (IOException e) {
System.out.println(e);
}
It returns blank page no output!
However i can execute run.exec("ls") / or ("gedit") and so on... and I GET DATA
Also i can execute internal programs that in my computer.
Why i cant execute .sh files or built-in java commands and getting blank page?
You should use ProcessBuilder to mix standard and error outputs:
ProcessBuilder run = new ProcessBuilder("java", "-version");
run.redirectErrorStream(true);
Process p = run.start();
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
for (String output = br.readLine(); output != null; output = br.readLine()) {
System.out.println(output);
}
} catch (IOException e) {
System.out.println(e);
}
Check that java parent directory is in your PATH variable (output System.getenv("PATH")) or use a full path to the binary.
For script, use /bin/sh like that ProcessBuilder run = new ProcessBuilder("/bin/sh", "/path/to/your/script");
All path can be absolute starting with /, or relative (without /) to System.getProperty("user.dir").
The jvm itself directs output to the error stream
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
If for example I chose to run a bash script that would output (echo) the time e.g. CheckDate.sh. How could I run this from Java and then print the result of the bash script (the date) in my Java program?
Try this code.
String result = null;
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec("example.bat");
BufferedReader in =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
result += inputLine;
}
in.close();
} catch (IOException e) {
System.out.println(e);
}
One way would be to assign your script execution in a Process object and retrieve the script ouput from its inputstream.
try {
// Execute command
String command = "ls";
Process process = Runtime.getRuntime().exec(command);
// Get the input stream and read from it
InputStream in = process.getInputStream();
int c;
while ((c = in.read()) != -1) {
process((char)c);
}
in.close();
} catch (IOException e) {
LOGGER.error("Exception encountered", e);
}
Another way would be to make your bash scripts write its output in a file and then read this file back from Java.
Good luck.
The java.lang.Process class is intended for such purposes. You run an external process in Java either using the (simpler) java.lang.Runtime.exec function, or the (more complex) java.lang.ProcessBuilder class. Both give you, in the end, an instance of said java.lang.Process, whose getInputStream method you can call to get a stream from which you can read its output.
See the Javadoc for more information.