There is a standard method, if the programs cooperate. Run kill -- -42
where 42 is the pid of the parent process. This sends a signal to all the processes in the process group lead by process 42 (the minus sign before the pid means process group).
Normally, if you run your python script from a shell prompt and it simply forks gnuchess
, the two processes should remain in the same process group. But this doesn't seem to be the case, since Ctrl+C sends SIGINT
to the whole foreground process group.
Gnuchess might be in its own process group because it made itself a session leader (but I don't know why it would do this), or because you've double-forked it (python forks a shell which forks gnuchess). A double fork is probably avoidable, but I can't tell you how without seeing your code.
A reasonably reliable and POSIX-compliant way of finding the pid of the gnuchess
process is
gnuchess_pids=$(ps -A -o pid= -o cmd= | awk '$2 ~ /(^|\/)gnuchess$/ {print $1}')
Specific unix variants may have better ways of achieving this, such as pgrep
.
Your question is not clear, you talk about a daemon in the title, but in the body only talk about a generic process.
For a daemon there are specific means to stop it, for example in Debian you have
service daemon-name stop
or
/etc/init.d/daemon-name stop
Similar syntaxes exist for other initscript standards used in other distributions/OS.
To kill a non-daemon process, supposing it is in some way out of control, you can safely use killall
or pkill
, given that they use by default the SIGTERM
(15) signal, and any decently written application should catch and gracefully exit on receiving this signal. Take into account that these utilities could kill more that one process, if there are many with the same name.
If that do not work, you can try SIGINT
(2), then SIGHUP
(1), and as a last resort SIGKILL
(9). This last signal cannot be catched by the application, so that it cannot perform any clean-up. For this reason it should be avoided every time you can.
Both pkill
and killall
accept a signal parameter in the form -NAME
, as in
pkill -INT process-name
Best Answer
summary:
You should use
jobs
to list, and usekill %n
to kill the n'th backgrounded process, and if your bash supports it :kill %-1
will kill the n-1'th backgrounded process.details:
Notice the additional "enter" needed to see the
[2]- Terminated find /./ -print >/dev/null 2>/dev/null
message (shown only before next prompt)Now, if your bash supports the
kill %-n
notation : it is easy:But if your bash doesn't support
kill %-1
: Here is an (overly complex...) attempt at automation (which should only kill if there is a n-1th job to be killed ... hopefully)(take out the "echo" once you're sure it does what you want it to ...)