p.waitfor() waits forever - java

i am trying to run commands using java program,but p.waitfor() function waits forever.What is wrong with the code?
import java.io.*;
public class doscmd
{
public static void main(String args[]) throws InterruptedException
{
try
{
Process p=Runtime.getRuntime().exec("cmd /c dir");
p.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=reader.readLine();
while(line!=null)
{
System.out.println(line);
line=reader.readLine();
}
}
catch(IOException e1) {}
System.out.println("Done");
}
}

Is the directory large? Maybe p fills up its output buffer and stalls waiting for a reader to consume something so it can finish writing out the directory listing.
You should probably move
p.waitFor();
to the end of the method.

You have to access your InputStream and ErrorStream before you're calling waitFor(). You should take a look at that question too for more details on how it works.

Your directory structure is too large. Move your p.waitfor() to
Process p=Runtime.getRuntime().exec("cmd /c dir");
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=reader.readLine();
while(line!=null)
{
System.out.println(line);
line=reader.readLine();
}
p.waitFor();
I tried running running this in C:\programfiles works fine.

Related

ProcessBuilder not outputting the correct output

private void printNumberOfRecords(){
try {
ProcessBuilder builder = new ProcessBuilder(
"/bin/sh", "-c",
"grep", "\"target-word\"", localFileName, "|", "wc", "-l");
Process p = builder.start();
p.waitFor();
BufferedReader br=new BufferedReader(
new InputStreamReader(
p.getInputStream()));
String line;
while(( line = br.readLine()) != null ) {
System.out.println(line);
}
}
catch( Exception e ) {
e.printStackTrace();
}
}
So I have the following code. The reads a file and counts the number of occurrences of a target word and prints the count. But when I run this function I don't see anything being printed.
Your code ask Java to wait until the subprocess sh end without reading the stream. When the buffer will be full, the subprocess wait, blocked.
Don't use p.waitFor(); until you read the output. The output stream will be closed when the process end.
To be complete, you have to check the error stream, too.
As Andreas noticed, a try-with-resource will be better.

ProcessBuilder - hanging on the readLine() method

Running the following simple program:
ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-Command", "dir");
Process p = pb.start();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
System.out.println("Exit");
Never reaches the "Exit" println - just hangs infinitely on the readLine() method. I understand this is (most probably) caused by the fact that powershell does not output \n in the last line and readLine is not sure whether the end has been reached or not. Is there a way to get over this issue and read the input stream correctly? BTW. inheritIO method on processbuilder resulted in the same issue...
UPDATE
This:
ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-Command", "dir");
pb.redirectErrorStream(true);
Process p = pb.start();
// BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
// String line;
// while((line = bufferedReader.readLine()) != null){
// System.out.println(line);
// }
p.waitFor();
System.out.println("Exit");
Also hangs infinitely...
Powershell isn't ending. I would probably use Java to list a directory, but this should work with your example.
ProcessBuilder pb = new ProcessBuilder("dir");
I had a problem with the processbuilder hanging on readline()
Specifically, windows 10, running a cmd.exe command that starts a bash and runs a script.
The problem was fixed by closing the input of the process:
Process process = pb.start();
process.getOutputStream().flush();
process.getOutputStream().close();
Not sure what the problem is. I tried making a new project with your code (added in a few try-catch and print statements), and it works for me. Here is what I used;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class temp {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-Command", "dir");
Process p;
try {
p = pb.start();
} catch (IOException e) {
System.out.println("Failed to start powershell");
return;
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
System.out.println("Begin!");
try {
while((line = bufferedReader.readLine()) != null){
System.out.println("reading...");
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Failed to read line");
return;
}
System.out.println("Exit");
}
}
And here is the resulting console output,
Begin! reading...
reading...
reading...
Directory: C:\Users\AbrahamV\workspace\201_stackoverflow reading...
reading...
reading... Mode LastWriteTime Length Name reading...
---- ------------- ------ ---- reading... d---- 12/10/2013 9:29 PM bin reading... d---- 12/10/2013 9:27 PM src reading...
-a--- 12/10/2013 9:27 PM 232 .classpath reading...
-a--- 12/10/2013 9:27 PM 393 .project reading...
reading...
Exit
The output wasn't instantaneous. Took a few moments before anything was printed out.

telnet connection inputstream blocking why?

package burak;
import java.io.*;
public class telcon {
public static void main(String[] args) {
try {
String[] command=new String[2];
command[0]="cmd /c start cmd.exe /k \"telnet\"";
command[1]="92.44.0.60";
Process p =Runtime.getRuntime().exec(command);
try {
p.waitFor();
} catch (InterruptedException e) {
System.out.println(e);
}
BufferedReader reader= new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=null;
line=reader.readLine();
File file =new File("rapor.txt");
file.createNewFile();
FileWriter writer=new FileWriter(file);
StringBuilder responseData=new StringBuilder();
while(line!=null) {
System.out.println(line);
responseData.append(line);
writer.write(line);
writer.close();
}
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();
}
}
}
i want to run telnet execute some commands i have two problem first when i connect to telnet it ask me username and password how ı contineude execute commands by using code after the enter password and my second question inputstream is not working readline is empty all time how can ı fix this problems.thanks for hel
I recommend you the Apache Commons Net Java library (http://commons.apache.org/proper/commons-net/) which contains various clients for many Internet protocols, including Telnet. I don't recommend you to use the embedded telnet client from the OS. Things will be cleaner with a library.
In addtion, in your first while loop, you're closing the writer object every iterations, and you don't read further with your reader.

Not able to capture output of "who -m" command in JAVA

I want to get the IP address of logged in user of the telnet session
So I have written the following code:
Process p1 = Runtime.getRuntime().exec(new String[] {"/usr/bin/who", "-m"});
p1.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String line = reader.readLine();
System.out.println("line=" + line);
reader.close();
But I am getting the output as "null".
Where as expected output is:
linus pts/1 Dec 10 03:48 (172.21.235.48)
In this case you shouldn't pass the -m option.
This works for me :
Process p1 = Runtime.getRuntime().exec(new String[] {"/usr/bin/who"});
Try to consume the input stream from the process before calling waitFor().
You can create a shell script which will receive parameter (option) from your java program.
Then you can run your shell script from java like this -
ProcessBuilder pb = new ProcessBuilder("/PATH/test.sh","-m");
String line;
Process process=pb.start();
java.io.InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
return br;
Now in test.sh, you cab grab the argument and run the command -
/usr/bin/who $1 (needs to check, not sure)
Hope this helps.
Thanks guys for the replies.
From the reply of "dystroy" I understood that -m was creating problem.
I tried --m and it worked :)
Please try this code. It's working for me and returns the same output as who -m UNIX command.
import java.io.*;
public class UserPB
{
public static void main(String[] args)
{
try {
// ProcessBuilder pb = new ProcessBuilder("/u01/app/chdir/user.sh");
ProcessBuilder pb = new ProcessBuilder("who");
Process p;
p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println("Your Host Details--->"+input.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

How to Execute Windows Commands Using Java - Change Network Settings

In Java, I want to be able to execute a Windows command.
The command in question is netsh. This will enable me to set/reset my IP address.
Note that I do not want to execute a batch file.
Instead of using a batch file, I want to execute such commands directly. Is this possible?
Here is my implemented Solution for Future Reference:
public class JavaRunCommand {
private static final String CMD =
"netsh int ip set address name = \"Local Area Connection\" source = static addr = 192.168.222.3 mask = 255.255.255.0";
public static void main(String args[]) {
try {
// Run "netsh" Windows command
Process process = Runtime.getRuntime().exec(CMD);
// Get input streams
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// Read command standard output
String s;
System.out.println("Standard output: ");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read command errors
System.out.println("Standard error: ");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
Runtime.getRuntime().exec("netsh");
See Runtime Javadoc.
EDIT: A later answer by leet suggests that this process is now deprecated. However, as per the comment by DJViking, this appears not to be the case: Java 8 documentation. The method is not deprecated.
Use ProcessBuilder
ProcessBuilder pb=new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process=pb.start();
BufferedReader inStreamReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while(inStreamReader.readLine() != null){
//do something with commandline output.
}
You can run the command with Runtime.getRuntime().exec("<command>") (eg. Runtime.getRuntime().exec("tree")). But, this will only run executables found in path, not commands like echo, del, ... But only stuff like tree.com, netstat.com, ... To run regular commands, you will have to put cmd /c before the command (eg Runtime.getRuntime().exec("cmd /c echo echo"))
public static void main(String[] args) {
String command="netstat";
try {
Process process = Runtime.getRuntime().exec(command);
System.out.println("the output stream is "+process.getOutputStream());
BufferedReader reader=new BufferedReader( new InputStreamReader(process.getInputStream()));
String s;
while ((s = reader.readLine()) != null){
System.out.println("The inout stream is " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works.
Runtime#exec().

Categories

Resources