I am trying to run multiple Nmap commands one after another.
Ideally, each Nmap command will be created in its own command prompt window. The Nmap command will execute and finish. Then another command prompt will appear with the next Nmap command, execute, and so on and so forth.
Unfortunately, the the way the program currently runs, multiple command prompt windows pop up at the same time and execute simultaneously. I want the commands to execute only one at a time. I had thought that the waitFor() method would solve the problem, yet it hasn't. Am I missing something?
I have simplified this greatly from my actual program to solve the core issue. Any help would be appreciated.
try {
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "start", "nmap", targets, "-p 1- 65535", "-oN +output");
Process p = pb.start();
p.waitFor();
System.out.println("p done");
Process z = pb.start();
z.waitFor();
System.out.println("z done");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This is because you are doing a "start". The process will start another one to handle the nmap command, and terminates without waiting for that child process to terminate.
Removing the "start" should make the windows show one after the other.
Related
Hey I tried to open IE from a java program.
the command start iexplorer works on command prompt and terminal but when used in a java program throws a IOException. When I execute the command cmd start iexplorer the program is just running without stopping for almost 15 minutes
String command = "cmd start iexplore";
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
This is the call stack of from VScode:
image
can someone help me with this please
All you are doing is running "cmd" in background. If iexplore is on your system Path then this may work:
String[] cmd = new String[] {"cmd", "/c", "start iexplore"};
The "/c" option tells CMD.EXE to start the process, and then CMD exits immediately [in your case it is hanging around for more input]. Also you need to read the STDERR stream of the process to see any error messages from CMD.
I am trying to set ulimit under which my java program runs. Currently, it seems that ulimit -n is set to 4096 because when I run this code (which is a part of my java program), it outputs 4096.
ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash", "-c", "ulimit -n");
try {
Process process = processBuilder.start();
// Prints 4096.
LOGGER_.info(getStringFromInputStream(process.getInputStream()));
} catch (IOException e) {
// The flow does not reach this catch block.
LOGGER_.error("exception caught: " + e.getMessage());
}
Is it possible to change it to something else, say 8192? I tried this:
ProcessBuilder processBuilder2 = new ProcessBuilder("/bin/bash", "-c", "ulimit -n 8192");
try {
Process process = processBuilder2.start();
LOGGER_.error("starting agent2...");
LOGGER_.error(getStringFromInputStream(process.getInputStream()));
} catch (IOException e) {
LOGGER_.error("exception caught2: " + e.getMessage());
}
and
try {
String[] cmdString = new String[3];
cmdString[0] = "/bin/bash";
cmdString[1] = "-c";
cmdString[2] = "ulimit -n 8192";
Process process = Runtime.getRuntime().exec(cmdString);
LOGGER_.error(getStringFromInputStream(process.getInputStream()));
} catch (IOException e) {
LOGGER_.error("exception caught:" + e.getMessage());
}
But I am not sure if these are the correct way to do so. Also, if the ulimit -n is even getting modified or not.
ulimit command updates the limits of the current process and all inherited processes. When you invoke ulimit using Runtime.exec or ProcessBuilder, it starts a new process and updates the limits of this new process with no effect on current Java process.
In order to apply new limits on itself, Java process should call setrlimit function in its own context. Since there is no Java wrapper for this function, it can be called only via a native interface: JNI, JNA or JNR.
However, if Java runs under unprivileged user, updating file limit (ulimit -n) is useless anyway, because HotSpot JVM updates this limit to maximum allowed value automatically - see this question.
I did a workaround that works. I was using a shell script that executed the java program. So, I set the ulimit before the shell script executed the running-the-java part. As answered by #apangin, this set the ulimit of the shell process and the java process that spawned from this shell process, inherited this ulimit.
I want to open JAR file by pressing JButton in JPanel. To achieve this goal I used ActionListener with ProcessBuilder inside. Here is my code:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ProcessBuilder pb = new ProcessBuilder("java", "-jar"
, "f:/Documents/TBot/topbotclient.jar"
, "-n", getTopBotName().getText()
, "-pw", getTopBotPass().getText()
, "-s", getScript_name().getText()
, "-w", getWorld().getText()
);
try {
Process p = pb.start();
} catch (IOException ee) {
ee.printStackTrace();
}
}
});
The problem is that opened JAR file do not function properly - it freezes after I press some of its buttons. However, if I close my initial JAVA window that is used to open external JAR, JAR file becomes functional again. What to do to get both initial window and opened JAR file window functional?
I did not find any solution by searching:
Run a jar File from java program,
Execute .jar file from a Java program etc.
UPDATE:
I tried not to use ProcessBuilder and used "runtime.exec" instead.
try {
Runtime runtime = Runtime.getRuntime();
runtime.exec(" java -jar f:/Documents/TBot/scripts/topbot.jar -n Fataho -pw diehard15 -s scriptjoiner -w 301 -nort -a b#hadas.lt -apw blood444");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Exception occured" + ex);
}
The problem remains the same.
Try to start a processbuilder in a separate thread so that your main thread won't block. From your code your doing everything in a Main thread. Make use of swingWorker kind of stuff to start the operation in a separate thread.
I am writing this question which is related to my previous topic:
Run bat file from java code to get desired result in txt file - no can do :(
In a shortcut: i wrote a program in java that runs a bat file. This bat file runs TestComplete8 script that performs desktop application test. After test is finished, bat file generates file called result.txt and prints information about test to it.
I'm stuck with another issue right now: Now from my java code i would like to wait until the bat run is finished. I do that by looping until the file called result.txt exists. Not the nicesest solution i guess but I thought it could work, also tried different solutions. What happens is that it will loop fine and wait until file exists, but testcomplete doesn't perform the test. It is very strange, because testcomplete runs, i can see that test starts, my AUT starts as well, but than nothing happens. Testcomplete is waiting for any object and doesn't click anywhere just waits until predefined time for action runs out. When i run the test without any waiting done in code, everything is fine. I just don't understand why nothing happens during the test when waiting is enabled and why it works fine when i just remove any do - while or waitFor(), or even i tried running it in seperate threads. :(
I have a feeling that it may be somehow related to the OS and have something to do with processes as it runs something like a bat as process and than bat runs it's child process as testcomplete or sth like that.
Thanks for any answers
Source code as asked:
Right now i was trying a solution with modified bat file:
#ECHO OFF
"C:\Program Files (x86)\Automated QA\TestComplete 8\Bin\TestComplete.exe" "C:..." /r /p:projname PathToApp="C:\...p" Login=... Password=B1 /t:"KeywordTests|..." /exit
and the code to run and wait in latest version is:
new Thread(new Runnable() {
public void run() {
File file = new File("D:\\");
int exitValue = -1;
try {
Process process = Runtime.getRuntime().exec(batch, null, file);
while (true) {
try {
exitValue = process.exitValue();
System.out.println(exitValue);
break;
} catch (IllegalThreadStateException e) {
// e.printStackTrace();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("Waiting for process...");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
The most likely cause, without knowing more about the problem, is a common one faced when launching external processes from Java. When launching an external process three streams are created between the parent and child process, input, output, error.
You can liken these to System.in, System.out and System.err. If the parent process (Java) does not actively consume the data on the out and error streams the child process may block as the OS will reach a buffer limit on the stream and prevent any more being written until it is consumed. This is quite likely if your script writes to standard out or standard error.
I would recommend using apache commons-exec to handle Java process launching.
Here's a code sample that I know works.
CommandLine commandLine = new CommandLine( "TestComplete8.bat" );
commandLine.addArgument( ... );
commandLine.addArgument( ... );
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue( 0 );
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
executor.setStreamHandler( new PumpStreamHandler( outputStream, errorStream ) );
try
{
executor.execute( commandLine );
}
catch ( ExecuteException e )
{
// TODO: ...
}
catch ( IOException e )
{
// TODO: ...
}
Then you can examine the output/error streams if you wish when execute returns.
try{
Process process;
process = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new
InputStreamReader(process.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
It depends on the command you wish to run, you may not need any. However, if your attempting to run a system level command you will need root access (not an Android permission). Running a platform command pretty much circumvents anything going on with Android permissions and is only affected by whether or not your linux user id has read/write/execute permission for the command you are issuing.
Runtime.exec() will also throw a SecurityException if you are not allowed to run a specific command and the exception will provide more details as to why in the specific case, so you should probably catch that in your try block also. You may also use Runtime.checkexec() to verify if you can run a certain command string before you actually attempt it.
Hope that Helps!
I assume that no permissions are necessary here. But you can analyze the result of execution in order to understand were the binary get executed.