Killing a process in Ruby is pretty straight forward. You just need to know the process ID for the process, and which signal you want to send:
Process.kill('INT', pid) # where pid is the process id of the process to be killed
A list of signals supported by your system is available from
Signal.list, but knowing which one to use is easier after looking at the definitions. I typically use
SIGINT (you can just use
INT in Ruby) to kill processes.
Something that I've always found messy (and error prone) is cleaning up a bunch of dependent processes that were spawned as part of an automated script. A common case for this is running integration tests where you have at least one process that is the server, a process that is running tests against that server, and potentially other helper processes for web browser automation, etc.
This is a hard problem because it isn't easy to know the process IDs for all of the child processes of a script. It may spawn additional processes, and commonly the process IDs returned to Ruby when spawning processes end up being incorrect due to redirection or process replacement.
It turns out that there is a simple UNIX solution to this problem: process groups. By sending a signal to a process group instead of a single process ID, we are able to send it to all of a script's child processes without knowing their individual process IDs.
To do this, use
Process.getpgrp to get the process group of the current process, and pass it to
Process.kill as a negative number, which indicates the argument is a process group and not a process ID. And since the current process is going to receive the signal as well, use
trap to catch it and provide a clean exit. In a script used for testing, use a non-zero exit status if any tests failed.
trap("INT") do exit end Process.kill('INT', -Process.getpgrp)
It appears that it is also possible to use
0 as the second argument to
Process.kill, and have the same behavior. For the sake of clarity, though, I prefer the former option.
Everything in this article should work in POSIX environments, but I have no idea if it will work on Windows.