0

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)?

pb2q
  • 58,613
  • 19
  • 146
  • 147
David
  • 23
  • 5
  • what is the host operating system? linux? Do you have admin privileges on the system? – pb2q Jun 18 '12 at 17:22
  • It is Linux. I am executing as a user with sudo privileges. – David Jun 18 '12 at 17:32
  • [Best way to kill all child processes](http://stackoverflow.com/questions/392022/best-way-to-kill-all-child-processes) is probably what you're looking for. – Go Dan Jun 23 '12 at 13:29

3 Answers3

3

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.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • +1 for additional tools, given that he has them installed or has privileges to – Morfic Jun 18 '12 at 17:26
  • I appreciate your extensive answer. I'm afraid I this solution is too heavy for my situation (dependence on those tools). – David Jun 18 '12 at 19:19
  • @David I'd suggest reading the linked wiki page, in that case. (That said, these tools may be already available to you -- Upstart, for instance, is the default init tool in modern Debian, Ubuntu, and Fedora). – Charles Duffy Jun 18 '12 at 20:18
0

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.

Morfic
  • 15,178
  • 3
  • 51
  • 61
  • pidfiles tend to have race conditions unless handled carefully (locked using flock or a similar tool during all read or update operations), and are prone to collisions (PID-table entries can be reused). They work, mostly, but aren't necessarily a best-practice. – Charles Duffy Jun 18 '12 at 17:29
  • agreed, but it's the solution I've used most, due to production environment restrictions and simplicity. That's also why you got a +1 :) – Morfic Jun 18 '12 at 17:32
0

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.

Community
  • 1
  • 1
Micromega
  • 12,486
  • 7
  • 35
  • 72