I have a shell script starting two java processes. How to ensure that when shell script process is killed, all It's children will be killed too? For example when I try to kill It, java processes remain alive:
kill -9 myscriptID
You can check for all java processes by running this:
ps -aux | grep *java*
This looks like it can help as well.
Your kill command only kills your script, not other processes that it has spawned. Best way to kill all child processes has some great answers for killing the whole tree.
That said, it seems that a better design would be to keep track of the PIDs of the child processes, and rather than sending the parent SIGKILL, send it SIGTERM (or have some other way) to trigger it to gracefully kill its children.
Related
I am trying to execute Java application from my c# code. I use Process class from System.Diagnostics.
I am able to run it and kill, but it seems that java starts subprocess when I am executing application. And when I am trying to kill the Process, I kill the parent java process, the second one, which was started behind the scenes, is still running.
Multiple executions of this logic cause dozens of java.exe processes and memory overflow.
Is there a way to do such thing as proper running Java application from c# code and be able to kill started processes?
I wonder if it is possible at all to resolve this issue if I don't have administrative rights
I would be tempted to use taskkill. It runs from this cmd command:
string.Format("cmd /c \"taskkill /f /pid {0}\" /t", this.processId);
the /t does a tree kill, that ends the child processes.
I have a init.d script which starts/stops a jruby based server running on java 8. It first does it the nice way with a kill and then after a while it falls back to a kill -9. I can see from my logs that the kill triggers the right shutdown hooks and eventually it calls System.exit(0). At this point the process should die, except it doesn't.
I've actually polled with a loop inside my init.d script whether the process still exists at that point (yes) and tried with a kill -QUIT to make it log a thread dump. The latter stops working after a few seconds but the process zombies along until I kill -9 it.
My question: how can I determine what is causing this? At least a thread dump would tell me what part of my code is blocking but it seems to be in a state where that no longer works and yet the process does not exit.
The suggestion by Joe to use Runtime.getRuntime().halt(int) works. Thanks
The scenario is as follows: I have a java daemon, which is supposed to not terminate. However, in case of an unexpected error, the crashed JVM should be restarted by a script. So I wrote a command which starts a background bash which has a loop starting the JVM (so when the JVM terminates, it will be restarted again).
/bin/bash -c "while true; do java ...; done" &
In order to be able to stop the daemon, I thought of killing this bash background process (by saving it's process id in a file). This works insofar as the background bash doesn't restart the JVM, but still doesn't kill the currently running process - so the bash seems to end it's current command before it checks for a kill command. I would like to have the currently running JVM to be killed, too.
Since I don't want to manage 2 PIDs (one for the background bash and one for the currently running JVM), is there a way of "force kill" which by design stops the current command? (I couldn't find such thing in man kill)?
There are a number of process-management tools built for exactly this purpose: runit, daemontools, upstart... even an entry in the SysV inittab table.
All of these will automate restarting immediately on shutdown, track desired status as opposed to current status (and attempt to signal startup or shutdown as-desired), manage signal delivery, etc.
You can trap signals in bash and trigger events on them, but that only handles the subset which can be trapped (you can't trap a KILL, for instance). The better thing is to use a tool built-to-purpose.
The ProcessManagement page of the wooledge.org wiki (used by irc.freenode.org's #bash channel) has some other concrete suggestions on doing this yourself in bash... though it too suggests runit, daemontools, and their kin as the best-practices approach.
Why not use cron to start your app, and manage only 1 pid, the one belonging to your app? That way you'll always be killing the correct process.
Emphasising a bit, you could create a bash script to manage your app: start|stop|status. On start it will save the java pid to a file. Then you can schedule a cron job to verify the status of the app, and if the pid does not exist, relaunch it.
Isn't this the default behaviour of bash? I thought for example zsh does the opposite and doesn't send a SIGHUP to all child process? Maybe you can try this answer and write a little script and start it with disown?
see this question: Tie the life of a process to the shell that started it
I didn't test it but I need zsh in my webserver because I start it manually and exit my shell with double CTRL-D.
I am starting an external process in my Java program (on Linux) and I need the ability to send it a SIGTERM signal rather than the SIGKILL that exec.getWatchdog().destroyProcess() is sending. Is there a way that I can more gracefully stop a unix process started with commons-exec? Or can I get the PID so that I can just run the appropriate kill command myself?
ExecuteWatchdog class has method for killing process.
So, you could just create a watchdog with long timeout and use it to kill process when neccessary, i.e.
executor.getWatchdog().destroyProcess();
Well, Commons Exec relies on the Java Process class, which doesn't expose a PID. It's also what is used to kill the process, so it's not something you can change the behavior of. All nice and encapsulated. Gotta love OO, eh?
If you are simply launching processes in to the background, you can wrap them in a simple shell script that captures the PID for you, and then saves that off to a "known place" that your Java routine knows about. Still kind of messy, and, naturally, it doesn't port to other platforms well.
You can write your own exec function using JNI to capture this information for you as well, but that's likely less friendly.
You could write a platform specific exec launcher daemon in something more system oriented (C, Python, etc.). You send IT messages to launch and stop things, and it handles that process for you. One benefit of this is that you don't have to fork the JVM when you run a new process (which can be quite expensive depending on your JVM size).
You can start the daemon up at the beginning and share a socket or a pipe (both pretty portable). That's actually not a horribly INelegant solution, and it compartmentalizes a lot of system specific behavior (so you can have a completely different process on, say, Windows vs Unix and your Java stays the same, you just need to port your little daemon), without having to run JNI.
Well you could grep it, for ex :
for i in $(ps -ef | grep -i "[Y]ourClassName" | awk '{print $2}'); do kill -9 $i; done
This is in case that you have it running more than 1 time(although it works if you have just one project), notice the [] in grep, that is so the grep doesn't give you its own process pid and -i stands for ignore case, awk is for printing second column only that is PID number.
I am using Java Runtime to run commands, including certain CVS commands.
I use:
process = runtime.exec ("cmd /C cvs...");
format for running the Process in Java
I need to have the option of stopping it. For this I use the Java Process destroy method
process.destroy();
However only the cmd is stopped not the cvs process. It continues to run as a separate process without the cmd process as the parent. There are many references to this on the internet, but I haven't found any satisfactory solution. Thanks
This is a problem with the windows cmd shell. Why do you use it? Can't you do exec("cvs ...") instead?
It may be possible using Runtime.exec to get the PID of the process you have run. And with that you might be able to shut down the process tree.
You would however need 2 other programs to find the PID and to terminate the process tree.