I am new to this console problems. I am simply creating a application which executes few command lines. I have a commands
mysql -u root -p
which is for opening MySQL console.
Here, how can I input password?
I did:-
cd c:\\Program Files (x86)\\MySQL\\MySQL Server 5.5\\bin
&& mysql -u root -p && root && create database testingdb;
&& quit && mysql –u root –p testingdb < mysql_dump.testingdb.sql
Here, first input is root which is password and second mysql_dump.testingdb.sql is sql file located in mysql_dump package.
This is not working and a thread is opened even though cmd console window is close.
How does java work in this situation?
Running the command
ProcessBuilder provides a full API for starting commands.
ProcessBuilder processBuilder = new ProcessBuilder("mysql", "-u", "root", "-p");
processBuilder.directory(new File("myDir"));
pb.redirectErrorStream(true);
Process proc = pb.start();
Pipe into the command
You can write strings into a BufferedWriter that wraps the confusingly named "output" stream from the Process object returned by processBuilder.start()
OutputStream stdin = proc.getOutputStream();
OutputStreamWriter osr = new OutputStreamWriter(stdin);
BuffererWriter bw = new BuffererWriter(osr);
bw.write("Hello\n");
A word of warning
You need to be very careful when using Process to consume the standard output/error streams otherwise the process can lock. A robust implementation should create 2 threads to read stdout and stderr asynchronously and perhaps a 3rd to feed the process.
The parent process uses these streams (#getInputStream(),
getErrorStream()) to feed input to and get output from the subprocess. 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, and even deadlock.
This guide When Runtime.exec() won't has all the information you need.
you can use Runtime class to execute OS commands. Since i donot have mysql installed canot check the senario mentioned. checked with cmd commands.
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("mysql -u root -p");
InputStream is = pr.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null){
System.out.println(inputLine);
}
Related
I need to find out how much memory a certain process (java.exe) is using from within a java webapp.
I have tried the following:
Process proc = Runtime.getRuntime().exec("tasklist /v | find \"java.exe\"");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader errInput = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
But this returns the following:
ERROR: Invalid argument/option - '|'.
Type "TASKLIST /?" for usage.
I know this is because a pipe is a shell feature and is parsed by Java before being passed to the shell.
I have also tried:
String[] procString = {
"cmd",
"/c",
"tasklist /v | find \"java.exe\""
};
Process proc = Runtime.getRuntime().exec(procString);
But this doesn't return anything to either BufferedReader.
Is there a way to get the correct output into the webapp?
The stdInput and errInput streams must be periodically consumed before the exec () function returns. The exec () function blocks whenever the buffer is full. That is, the command through the exec () function does not proceed when there is no space to write to the buffer. To solve this problem, read the buffer after each buffer is full in another thread.
It is a mistake that is easy for a person who gets into a Java program. If you have defined a stream, it must be consumed (via the read function)
Hi friends I want to open cmd on server.I have a java code on my local machine that run a batch file(Run.bat) on server the code runs successfully but does't open a cmd.exe on server, but whenever I go to server and double click on my batch file on server it's open a cmd.
Thanks in advance.
java code:
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c",
"F:\\Softwares\\PsTool\\PsExec.exe \\\\aa.aa.aa.aa -u Administrator -p 1234 \"c:\\batch\\Run.bat\"");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) {
break;
}
System.out.println(line);
}
Run.bat:
start cmd
Pretty simple. As the docs state:
By default, the subprocess writes standard output and standard error to pipes. Java code can access these pipes via the input streams returned by Process.getInputStream() and Process.getErrorStream(). However, standard output and standard error may be redirected to other destinations using redirectOutput and redirectError.
Simplified: the ProcessBuilder doesn't generate any Console-Windows, but instead simply redirects output from any command to a pipe that can be read from the javaapp.
Everything works fine on the command line, but when I translate what I want into Java, the receiving process never gets anything on stdin.
Here's what I have:
private void deployWarFile(File warFile, String instanceId) throws IOException, InterruptedException {
Runtime runtime = Runtime.getRuntime();
// FIXME(nyap): Use Jsch.
Process deployWarFile = runtime.exec(new String[]{
"ssh",
"gateway",
"/path/to/count-the-bytes"});
OutputStream deployWarFileStdin = deployWarFile.getOutputStream();
InputStream deployWarFileStdout = new BufferedInputStream(deployWarFile.getInputStream());
InputStream warFileInputStream = new FileInputStream(warFile);
IOUtils.copy(warFileInputStream, deployWarFileStdin);
IOUtils.copy(deployWarFileStdout, System.out);
warFileInputStream.close();
deployWarFileStdout.close();
deployWarFileStdin.close();
int status = deployWarFile.waitFor();
System.out.println("************ Deployed with status " + status + " file handles. ************");
}
The script 'count-the-bytes' is simply:
#!/bin/bash
echo "************ counting stdin bytes ************"
wc -c
echo "************ counted stdin bytes ************"
The output indicates that the function hangs at the 'wc -c' line -- it never gets to the 'counted stdin bytes' line.
What's going on? Would using Jsch help?
You might try closing the output stream before you expect wc -c to return.
IOUtils.copy(warFileInputStream, deployWarFileStdin);
deployWarFileStdin.close();
IOUtils.copy(deployWarFileStdout, System.out);
warFileInputStream.close();
deployWarFileStdout.close();
Would using Jsch help?
Using JSch would only help if you would be using the setInputStream() and setOutputStream() methods of the channel instead of the IOUtils.copy method, since they manage the copying on a separate thread.
ChannelExec deployWarFile = (ChannelExec)session.openChannel("exec");
deployWarFile.setCommand("/path/to/count-the-bytes");
deployWarFile.setOutputStream(System.out);
deployWarFile.setInputStream(new BufferedInputStream(new FileInputStream(warFile)));
deployWarFile.connect();
(Here you somehow have to wait until the other side closes the channel.)
If you simply replaced the Runtime.exec with opening an ChannelExec (and starting it after getting the streams), the problem would be completely the same, and could be solved by the same solution mentioned by antlersoft, i.e. closing the input before reading the output:
ChannelExec deployWarFile = (ChannelExec)session.openChannel("exec");
deployWarFile.setCommand("/path/to/count-the-bytes");
OutputStream deployWarFileStdin = deployWarFile.getOutputStream();
InputStream deployWarFileStdout = new BufferedInputStream(deployWarFile.getInputStream());
InputStream warFileInputStream = new FileInputStream(warFile);
deployWarFile.connect();
IOUtils.copy(warFileInputStream, deployWarFileStdin);
deployWarFileStdin.close();
warFileInputStream.close();
IOUtils.copy(deployWarFileStdout, System.out);
deployWarFileStdout.close();
(Of course, if you have longer output, you will want to do input and output in parallel, or simply use the first method.)
You probably get an error, but the process hangs because you are not reading the error stream.
Taken from the Process JavaDoc
All its standard io (i.e. stdin, stdout, stderr) operations will be redirected to the parent process through three streams (Process.getOutputStream(), Process.getInputStream(), Process.getErrorStream()). The parent process uses these streams to feed input to and get output from the subprocess. 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, and even deadlock.
So you need to read all of them. Using the ProcessBuilder is probably easier
I have a command line tool that queries a server and prints the status of pending jobs to run. This can take up to 30 seconds. I need to call this tool from java and I want to show its output in a text area on my GUI. For the purposes of example, lets say the command is "dir" in windows.
Process.getRuntime().exec("cmd /c dir"); blocks until the command finishes executing, so I thought it would be best to show the command executing in the terminal, then read the output and show it in my text area for future reference. However, the console is hidden giving the user the impression that the application has stopped working. After much research, I have tried:
cmd /k dir - runs in the background and can read output, but application hangs as it requires the /k switch means to keep the window open, but I can't see it to close it.
cmd /c start dir - opens in a new visible terminal, runs but doesn't close. Closing manually doesn't allow me to read the output
cmd /k start dir - same result as above
My question is, how can I spawn a command to run, see it running, and access its output?
Process proc = null;
String[] cmd = { "cmd", "/c", "dir" };
proc = Runtime.getRuntime().exec(cmd);
InputStream inputStream = proc.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null)
{
System.out.println(line);
}
You can grab its input / output / error stream using the process methods. but you need to get the process object - Process p = Process.getRuntime().exec("cmd /c dir"); see this answer also.
I am trying to execute a program from the Java code. Here is my code:
public static void main(String argv[]) {
try {
String line;
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
My OS is Mac OS X 10.6.
Now, the executable I am trying to run is supposed to spit the output to filename.txt. If I take this command and run it on the terminal, it works fine and the filename.txt gets populated also. But, from my java program the file is not created.
if instead I use executable > filename.txt then the filename.txt is created but is empty. Not sure what's wrong here. The executable I am trying to run is Xtide (if that helps).
I would really appreciate any help I can get.
Thanks,
You cannot redirect output to file and read the output in java. It's one or the other. What you want is this:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable -o filename.txt"});
p.waitFor();
BufferedReader input = new BufferedReader(
new InputStreamReader(new FileInputStream("filename.txt")));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
The main changes are:
p.waitFor(), since process execution is asynchronous, so you have to wait for it to complete.
The data is read from the file rather than from the output of the process (since this will be empty.)
The answer from mdma works (and I voted it up), but you might also want to consider the version where you do read the output stream directly from executable:
Process p = Runtime.getRuntime().exec(new String[]{
"/bin/bash", "-c", "executable"});
p.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
Correct me if I am wrong, but the symptoms are as follows:
exec("/usr/bash", "-c", "executable > filename.txt") creates an empty file.
exec("/usr/bash", "-c", "executable -o filename.txt") does not create a file.
One or both of the above gives an exit code of 255 when you look at it.
When you run the command from the command line as executable -o filename.txt or executable > filename.txt it works as expected.
In the light of the above, I think that the most likely cause is that /bin/bash is not finding the executable when you launch it from Java. The fact that the first example does create an empty file means that /bin/bash is doing something. But if you try to run
$ unknown-command > somefile.txt
from a bash shell prompt you will get an error message saying that the command cannot be found and an empty "something.txt" file. (You would not see the error message in your Java app because it is being written to stderr, and you are not capturing it.) The reason that the empty "something.txt" file is created is that it is opened by the shell before it attempts to fork and exec the "executable".
If this is the problem, then the simple solution is to use the absolute pathname for the executable.
Also, if you are not doing any command line redirection or other shell magic, there is no need to run the executable in a new bash instance. Rather, just do this:
Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt");
then wait for the process to complete and check the exit code before trying to read the file contents.