I am making a program to automatically backup a MySQL database from within java using MysqlDump. I want to get the file created and zip it. However, I am having an issue with the MySQLDump.
I am using the following to create a MySQLDump:
Process pr = Runtime.getRuntime().exec(
"mysqldump -u "+user+" --password='"+password+"' "+database+" > /root/moltres/backups/sql/"+database+".sql"
);
I have a while loop after this which remains in the loop if pr.isAlive(). I thought this would work, but it appears that when the command is executed, the process instantly becomes no longer alive. I could make the thread sleep, but for how long? How can I make the same SQL backup, but detect when the mysqldump command has completed?
The command is exiting immediately all right. It is failing, because the redirection isn't being understood by mysqldump.
This is not how you use Process. You need to:
Use ProcessBuilder.
Merge the output and error streams.
Add sh -c or cmd /c as appropriate to the beginning of the command line to handle the redirection.
Start the process.
Consume the output stream and log it, reading until end of stream.
Call Process.waitFor().
Get the process's exit code and log that.
Why you're using Java for this at all is a mystery. It's just a shell script. Indeed you can get MySQL to schedule its own backups automatically, without even needing a script.
Related
I am trying to make a console-based Java application that starts some batch scripts that do some other irrelevant things. Presently, I just want to find the proof of concept
I have tried to use the following code:
Runtime.getRuntime().exec("cmd /c start pathtomybatch.bat");
This works fine until I turn it into a .jar file and attempt to execute it. Then it opens the batch file in a new command prompt window, which I don't want it to do. I want to open the batch file in the same window that my Java program is running in. I read about the start command on TechNet and SS64 and found out that apparently adding changing start to start /b would open the program in the same command prompt window. However, when I try to run this:
Runtime.getRuntime().exec("cmd /c start /b pathtomybatch.bat");
NetBeans says BUILD SUCCESSFUL for both lines of code, but when I try the second line of code, no command prompt window opens and my batch file doesn't get started.
I want to know how I can make Java open that batch file within the same command prompt window without stopping the Java application or waiting for it to finish.
Also, as a tiny extra request, could someone tell me if I could do the same for an .exe file?
I'm on Windows 7, but I want this app to work for people using Vista or newer.
The extra window is coming from the start command you initiate. See https://www.windows-commandline.com/cmd-start-command/
A better pattern is to use
Process p = Runtime.getRuntime().exec("cmd /c pathtomybatch.bat");
Then make sure you loop until p.exitValue() no longer throws an exception (which means the process has exited), and while looping copy all available bytes from p.getOutputStream() and p.getErrorStream() to System.out and/or System.err.
I was able to use an amalgamation of SO questions to get a line of code that would:
Run a batch file from within a Java application
Include an argument located in the same directory as the batch file
The argument & batch file are in a directory unrelated to the JAR/java app
So I used this:
Runtime.getRuntime().exec("cmd /c start batchfile.bat argument.js", null, new File( path ));
This works well except that it leaves the cmd prompt open after it has finished executing the batch file. I've looked around and it seems like having the /c flag should make it close after running, but for me it has been staying open. I tried removing 'start' but this meant that the cmd prompt never opened up at all.
Is it because I'm combining having an argument and using a different path that it's not causing the cmd prompt to open and then close after completion like most examples on SO?
Calling both cmd.exe and start in that order is creating a separate window but it doesn't seem like the command shell is terminating based on what you described. I was able to replicate this behavior in a simple batch script. If you want to leave your Java call as it is, check to make sure your batch script includes an exit statement. Preferably exit based on a success or failure condition within your batch script (i.e.: exit 0 or exit 1, etc...)
:: batchfile.bat
...
exit 0
Assuming you are not firing up any new shells within your batch script or prompting for input, adding an explicit exit to your existing batch script should cause the window to close. You can also try to leave your batch script as is, and as others have suggested in comments, change the order of your command text slightly.
Use this instead
start cmd.exe /c ...
Where you call start first and then call cmd.exe /c after followed by your parameters as needed. I tried both options here and either worked fine to cause the batch window to close as expected.
Pass the below command to Runtime to execute.
taskkill /F /IM (processName)
Runtime.getRuntime().exec("taskkill /F /IM "+pProcessName);
I've been coding a litte bash script which connects on several distant servers, then execute a java CLI program through a few expect instructions.
It goes like this :
bash script
expect
ssh to server using public keys
expect ...
expect ...
log_file my_file (everything displayed on the screen is now redirected to my_file)
expect ...
log_file (closing my_file)
exit
exit
When I execute my script manually everything runs OK.
When I execute it through crontab, the file my_file is empty.
I found out that cron jobs don't have a tty attached and that PATH isn't the same as usually
My question is : is there a way to force the creation/allocation of a tty to my cronjob?
I've tried using the -t and -tt option with ssh but no result.
redirecting standard output on different levels of the script didn't work.
Also, I can't install screen (which could have helped, maybe) and "script" isn't writing anything either.
Thanks a bunch!
You can check the cron tab log for erros and make sure the full path is given for the command to be executed.
I have a shell script test.sh that does:
cat /home/tomcat/temp/tempLogFile.log > /home/tomcat/temp/logFile_test.log
I call test.sh from java by Runtime.getRuntime().exec("test.sh")
It creates the logFile_test.log but nothing written to it.
If I run the script directly from shell, it works fine.
What could be going wrong?
Thanks,
UPDATE: Interstingly, it works fine if I do
echo 'cat /home/tomcat/temp/tempLogFile.log > /home/tomcat/temp/logFile_test.log' | at now
But I cant use at now since I need to wait for cat to finish
Maybe your command path is messed up? That command will create logFile_test.log even if it can't run the cat program. Try adding something like:
set > /tmp/dump.txt
to the shell script. This will write a copy of the process's environment variables to /tmp/dump.txt. Inspecting those might help you figure out the problem.
Another possibility is that the disk is full. In that case, you'd be able to create empty files, but not write any data to them.
Once you invoke the getRuntime().exec("ANY_COMMAND"); , it returns you an instance of Process, using process object you can get Input and Output Streams and then pass any other command to the same process or read the output , for that purpose you have three streams connected
Output Stream :- Gives you Control to send more arguments or commands to the same process
Input Stream :- Gives you Control to read the values from the stdout of the process
Error Stream :- Gives you all the errors that were occured during execution of any command.
even if you have any errors, you can check the error stream and see whats going wrong.
you may refer Java process.getInputStream() has nothing to read, deadlocks child
I am trying to write a simple application that takes in a command line arguement (which will be a Powershell ps1 file) and then run it. So I have experemented with a number of different approaches and seem to be running into a problem. If I attempt to invoke powershell from within java, the windows process is started and is visible via process explorer, however powershell never returns, it hangs in some sort of loop by the looks of it. The command I am using is:
String command = "powershell -noprofile -noninteractive \"&C:\\new\\tst.ps1\"";
The command is then executed using:
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
At the moment I am hard coding the location to the ps1 file as I was trying to rule this out as an issue. Using a process explorer I can see the hanging powershell process and the command that was passed to it was :
powershell -noprofile -noninteractive "&C:\new\tst.ps1"
which when copied into a cmd window, works to launch the tst.ps1 file. The file itself is incredibly simple in this example and I think I can rule it out being the cause of the freeze as I have tried to launch other ps1 files the same behaviour can be seen.
To further add to the confusion, if I use the java code posted above and pass in powershell commands instead of a file name then it successfully runs.
I've scoured the web and see lots of people experiencing the same issue but no one seems to have posted there solution, I hope its a simple oversight on my part and can be easily fixed.
Any hints/tips are appreciated :D
Alan
You have to close OutputStream in order for Powershell to exit.
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
proc.getOutputStream().close();
Is your external program writing to the standard outputs (err and out)?
If yes, it can hang waiting for you to consume them from the java parent process.
You can get those as InputStreams by calling
Process.getInputStream()
and
Process.getErrorStream()
There's more details here:
Javadoc for Process