I have the following code in java that calls the date command in the command prompt:
// prepare command prompt runtime and process
Runtime runtime = null;
Process process = null;
// prepare output stream
OutputStream outputStream = null;
try {
runtime = Runtime.getRuntime(); // instantiate runtime object
process = runtime.exec("date"); // get the current date in command prompt
// read the output of executing date command
outputStream = process.getOutputStream();
// output the date response
System.out.println(outputStream);
process.waitFor(); // wait for the date command to finish
} catch(Exception e) {
e.printStackTrace();
} // end catch
How can I read the outputStream value for me to be able to use the System.output.println()
You don't read the output stream, you write to it to pass data to process. To read the data from process use
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
br.readLine();
The code is for string output of process. Of course if your process outputs data in other way you have to change the wrappers around process.getInputStream()
Update: I think it is in some way confusing that we use getInputStream to actually read process output :) The reason is that initially basic classes OutputStream and InputStream were named so relatively to the code that uses them (the code you write). So when you use OutputStream you actually use it as output for your program. When you use process.getOutputStream you don't get process' output but instead get your program output which is piped to process input. When you use process.getInputStream you get input for your program which obtains data piped from process' output.
you can do like this way without using OutputStream object
Process p = Runtime.getRuntime().exec("date");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
String answer = sb.toString();
System.out.println(answer);
Related
I'm trying to execute a script via JAVA code, but it's not being executed. I tried execute() of Process class but later switched to ProcessBuilder after some searching hoping to make this work. But the script's not getting executed.
JAVA Code:
String fileName = "pkgdiff.sh";
File file = new File(fileName);
ProcessBuilder builder = new ProcessBuilder("/bin/sh", fileName);
builder.directory(file.getParentFile());
Process process = builder.start();
process.waitFor();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
LOGGER.info("### Script Execution result --> " + fileName+"-->" + output);
Script file:
#!/bin/sh
.. rest of the content
How much output is the script producing? You should be processing its output before you call waitFor(), otherwise the process might block if it fills up its output buffer.
From the Java API:
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
I have a project that use command prompt to complie java file,then print the result in console,this is mycode.
public static void main(String[] args) {
String line;
String output = "";
try {
Process p = Runtime.getRuntime().exec("java helloworld");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + '\n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
System.out.print(output);
}
But it show nothing,although it work with another command,please help me.
As one of the commenters mentioned this might result in quite complex setups you are running into. It is most likely in your case that an error happens in java and you just do not see the output since error messages are written to the STDERR stream instead of STDOUT.
So there are two options (1) you take the code you already have and also try to read from the process' ErrorStream.
Bufferedreader error = new BufferedReader(new InputStreamReader(p.getErrorStream());
Or if you do not care whether or not the process you were starting was writing to STDERR or to STDOUT you can also use a ProcessBuilder and just set it up to redirect the error stream.
ProcessBuilder pb = new ProcessBuilder("java", "helloworld");
pb.redirectErrorStream(true); // this redirects STDERR to STDOUT
Process p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + '\n');
}
input.close();
For the sake of simplicity I omitted all the boilerplate code and exception handling in the above. But I think you will get the idea.
Why are you using the Process builder and executing the same. Why not use JavaCompiler interface. See the documentation it is really well written.
I'm working on reading the output of a script that is invoked using a Java process. However, in the middle of the script run, it will in SOME situations prompt the user to answer y/n to continue. However, after reading many posts on StackOverflow, I'm still stuck with detecting the prompt and then sending the response while the process is still running.
If anyone has any ideas, that would be awesome.
I've tried reading from Scanner class and System.console to no prevail.
Here is a portion of the code I'm using.
Process p;
String file = "./upgrade.sh";
cmds.add(file);
cmds.add(sourcePath);
cmds.add(outputDirectoryPath);
cmds.add(zip);
cmds.add("-c");
//}
pb = new ProcessBuilder(cmds);
pb.directory(new File(binDir));
p = pb.start();
BufferedReader reader = new BufferedReader (new InputStreamReader(p.getInputStream()));
BufferedReader reader2 = new BufferedReader (new InputStreamReader(p.getErrorStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
try
{
String line = reader.readLine();
while (line != null)
{
System.out.println(line);
line = reader.readLine();
}
reader.close();
writer.close();
}
catch (IOException e)
{
e.printStackTrace();
}
p.destroy();
The problem is that you use a BufferedReader. It will only return when it has read a full line, that is a line separator. But if the script asks for something with a prompt, there won't be a line separator! As a result it WILL NOT return.
You have to use some other kind of reader in order to control the process.
For some terminal commands, they repeatedly output. For example, for something that's generating a file, it may output the percent that it is complete.
I know how to call terminal commands in Java using
Process p = Runtime.getRuntim().exec("command goes here");
but that doesn't give me a live feed of the current output of the command. How can I do this so that I can do a System.out.println() every 100 milliseconds, for example, to see what the most recent output of the process was.
You need to read InputStream from the process, here is an example:
Edit I modified the code as suggested here to receive the errStream with the stdInput
ProcessBuilder builder = new ProcessBuilder("command goes here");
builder.redirectErrorStream(true);
Process process = builder.start();
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
For debugging purpose, you can read the input as bytes instead of using readLine just in case that the process does not terminate messages with newLine
I want to execute some sql scripts using Java's Runtime.exec method. I intend to invoke mysql.exe / mysql.sh and redirect the script file to this process.
From the command prompt I can run the command
<mysqInstallDir\/bin\mysql.exe -u <userName> -p <password> < scripts\create_tables.sql
I can invoke mysql.exe using Runtime.exec but how do I redirect data from sql file to mysql.exe ?
I read the article in http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 and used the StreamGobbler mechanism to get the error and output streams. No problem there. The problem comes in reading the file "scripts\create_tables.sql" using BufferedReader and passing the contents to prcess's outputstream. I was expecting the Process to pass the data to the mysql.exe. But I see that only the first line is read from this sql file.
OutputStream outputstream = proc.getOutputStream();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter);
while ( (line = br.readLine()) != null)
{
bufferedwriter.write(line);
bufferedwriter.flush();
System.out.println(line);
}
bufferedwriter.flush();
bufferedwriter.close();
proc.waitFor()
When I do this I see that only the first line in create_tables.sql is executed. The exit code for the process is 0 and there is other no error or output.
Exec returns a Process object to you.
Process has getInputStream and getOutputStream methods.
Just use those to grab the input stream and start shoving bytes into it. Don't forget to read the output stream or the process may block.
Redirection is a functionality of the OS shell/cmd enviroments. To invoke them correctly we should use Runtime.exec(String[]) instead of Runtime.exec(String).
Here is the code.
public Result executeCmd(String[] cmds, boolean waitForResult)
{
Result result = new Result();
result.output = "";
try
{
for(int i=0;i<cmds.length;i++)
{
System.out.println("CMD["+i+"]::"+cmds[i]);
}
System.out.println("");
Process process = null;
if(cmds.length > 1)
process=Runtime.getRuntime().exec(cmds);
else
process=Runtime.getRuntime().exec(cmds[0]);
if (waitForResult)
{
StreamGobbler errordataReader = new StreamGobbler(process
.getErrorStream(), "ERROR");
StreamGobbler outputdataReader = new StreamGobbler(process
.getInputStream(), "OUTPUT");
errordataReader.start();
outputdataReader.start();
int exitVal = process.waitFor();
errordataReader.join();
outputdataReader.join();
result.returnCode = exitVal;
result.output = outputdataReader.output;
result.error = errordataReader.output;
}
}
catch (Exception exp)
{
result.exp = exp;
result.returnCode = -1;
}
return result;
}
And call this method using
Result result = executeCmd(cmds, true);
where
CMD[0]::cmd
CMD[1]::/c
CMD[2]::.\mysql\bin\mysql --host=<hostname> --port=<portNum> -u <userName> < .\scripts\create_tables.sql