Over at his Command-Line Kung Fu blog, Hal has posted a solution to the problem of writing a process-whack-a-mole command, that watches for any new process and kills it.
(Hal's self-imposed constraint is always that his solutions really be command lines -- they can't be full-blown scripts -- and that they not use Perl, or other languages that are powerful enough that their use would feel like cheating.)
Nothing wrong with his approach at all, but here's another. (I mailed it to Hal, who said, "Post it somewhere, Dude.")
$ ps -e o pid,ppid,cmd | grep -v $$ > baseline; while : ; do> sleep 5> ps -e o pid,ppid,cmd | grep -v $$ > now> join -v 2 baseline nowdone
It shows off a couple of things:
- join -v
- the output of ps is pre-sorted by process-number
The didactic downside? It doesn't show off arrays or "[[" . (I spent a minute in philosophical reverie, contemplating the elevated virtue of using files to store data for shell scripts, but then realized this is engineering and snapped out of it.)
Oh, and I completely love Hal's "| grep -v $$", which I never would have thought of.
On reflection, the only thing the join would normally see is the ps itself, which is gone by the time of the join, so for the real deal, this can be pared down a titch.
# ps -e o pid,cmd > baseline; while : ; do> sleep 5> ps -e o pid,cmd > now> kill -9 $(join -v2 -o2.1 baseline now)done 2>/dev/null &
Just kill everything new and ignore the error message from not being able to kill the ps:
"Kill them all and let The Kernel sort them out."