I am using below code to trigger script of Unix through Java.I am not able to figure out why this command is not working.
String cmd="E:\\plink.exe -ssh -l user -pw p123 10.xxx.xx.xx \"sh /home/try.sh\"";
System.out.println(cmd);
Process process=Runtime.getRuntime().exec(cmd) ;
process.destroy();
Do i need to make some correction in it?
Runtime.exec only starts the specified program/process. You immediately destroy it before it has time to connect and send the commmand, as you want it to. At a minimum you should .waitFor() it to complete.
You don't say if the script produces (any) output. If it does and you want anything to happen with that output, like being displayed or saved someplace, you need to read from Process.getInputStream() and do your thing. Also if your script needs input (less common) you need to write it to .getOutputStream().
Related
I am working on java process builder to execute the windows external process(i.e., exe files). I have to get the process info and error using input stream, error stream to write it in some text files.
It's working sometimes and unexpectedly hanging sometimes.
When i invoke around three external process to execute one by one. Two process working and it's getting hang on third process only.
I could see the process exit value as 0 some times it's giving some other random value.
I have read the below blog and applied the same logic to execute the process but's not working for my scenarios.
Could anybody please help me to diagnose these problem...
//Starts to initiate the external process
//This code will pick three arguments from to execute the process sequentially
//it will pass the process commands through for loop one by one
Process p =new ProcessBuilder(s)
.directory(new File(je.getExecution().getWorkingDirectory()))
.redirectErrorStream(true)
.redirectOutput(file)
.start();
p.getOutputStream().close();
int processStatus= p.waitFor();
// if the process exits with 0 normal termination
Thanks in advance..,
The entire thing you are doing is error prone and it’s not worth trying to find out all of the mistakes, as you are making your life unnecessarily hard.
Note that you are calling redirectErrorStream(true), but still are trying to read from the error stream, which makes no sense. The error stream will always be empty under this condition. That said, if you already know about redirections, it’s not clear, why you don’t use them directly, instead of creating threads, manually copying data into StringWriters, etc.
Apparently, you want to use the working directory je.getExecution().getWorkingDirectory(), launch the command s and directing both, output and error, of the program to file. This can be achieved as easy as
new ProcessBuilder(s)
.directory(je.getExecution().getWorkingDirectory())
.redirectErrorStream(true).redirectOutput(file)
.start()
.waitFor();
The only remaining error source is that the launched process could wait for input from your side. Since you apparently don’t want to provide input, you can use
Process proc = new ProcessBuilder(s)
.directory(je.getExecution().getWorkingDirectory())
.redirectErrorStream(true).redirectOutput(file)
.start();
proc.getOutputStream().close();
proc.waitFor();
to denote that you won’t write any data. This will not stop the process, but when it tries to read something from its standard input, it will immediately get an end-of-file without blocking.
Which can be demonstrated with
Process proc = new ProcessBuilder("cmd", "/c", "pause")
.redirectErrorStream(true).redirectOutput(file)
.start();
proc.getOutputStream().close();
proc.waitFor();
I am using java to call arp -s command and waiting for the process to finish in order to complete function .
String command ="arp -s "+entryIpAddress+" ee-ee-ee-ee-ee-ee-ee";
Process p=Runtime.getRuntime().exec(command);
p.waitFor();
but the calling of this process is taking more than the usual time so, is there a way to increase the performance of this method. i cannot remove the p.waitFor() my next function depend on the added entry.
Your code doesn't show any sign of effort towards allowing the process to complete ever. You are not consuming its output, so its output buffer will soon fill up, blocking further progress.
To make this task easier on yourself, please use the ProcessBuilder.
I'm trying to benchmark execution time for a program I created. As I add more data for it to process it takes longer and I am trying to find out how long exactly and a few details about the program(number of loops, time for each loop,etc..) so I created a system.out.println... of the status messages I want. This program works with a small number of variables quickly, but to run it on a large amount I do: java my_program > results.txt &
I see the job running for about 2 hours than it vanishes, so assuming its finished I try to cat results.txt but its blank. If java was crashing, wouldn't the error message be in there also(I think I'm capturing all output)? If not, is there a place I can find this information?
You redirected stdout to a file, but any errors would have been written to strderr, which was not redirected. See http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html for an example of how to redirect both stdout and stderr
You can do something like this
java my_program 1>results.txt 2>error_log.txt &
This would actually redirect your errors to error_log.txt and your sysouts to results.txt
I have started a process in my Java code, this process take a very long time to run and could generate some output from time to time. I need to react to every output when they are generated, what is the best way to do this?
What kind of reaction are you talking about? Is the process writing to its standard output and/or standard error? If so, I suspect Process.getInputStream and Process.getErrorStream are what you're looking for. Read from both of those and react accordingly. Note that you may want to read from both of them from different threads, to avoid the individual buffer for either stream from filling up.
Alternatively, if you don't need the two separately, just leave redirectErrorStream in ProcessBuilder as false, so the error and output streams are merged.
You should start a thread which reads from the Process.getInputStream() and getErrorStream() (or alternatively use ProcessBuilder.redirectErrorStream(true)) and handle it when something shows up in the stream. There are many ways that how to handle it - the right way depends on how the data is being used. Please tell more details.
Here is one real-life example: SbtRunner uses ProcessRunner to send commands to a command line application and wait for the command to finish execution (the application will print "> " when a command finishes execution). There is some indirection happening to make it easier to read from the process' output (the output is written to a MulticastPipe from where it is then read by an OutputReader).
I have asked this question before.
I am having the following requirement.
Run the batch file.
Give some time to run the batch file.
3.Close the batch file
I have the following code that does not meet the requirement. Please tell me where I have made a mistake
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
//pr.exitValue();
//wait(10000);
pr.waitFor();
pr.destroy();
I have used the waitFor that does not work. How can I give a delay for about 15 minutes after executing the batch file
If you do not have threads reading the stdIO from the batch process, the batch process can block. Even if you are not interested you still ned to read it and discard it. Then your wait for has a better change of working.
I'm not sure what you want, but with
Thread.sleep(900000);
you can wait for 15 minutes.
A suggestion: grab the output and error streams and see what they are printing out. You may see that there is an error happening with the batch file making it return sooner than you expect.
Your question did not mention giving a delay in Java. You imply that the delay should be in the batch file after the Java program executes. Therefore, you can configure it for any amount of time. Here is a 20 second example:
#ECHO off
REM.-- End of application
:: do something here
GOTO :END
:: you could put functions here
:END
FOR /l %%a in (20,-1,1) do (TITLE %title% -- closing in %%as&ping -n 2 -w 1 127.0.0.1>NUL)
TITLE Press any key to close the application&ECHO.&GOTO:EOF
PAUSE>nul