## 24.15. Killing Processes by Name?

This article discusses a particular version of kill that has some problems. Your system may have a different kill and, possibly, a version of killall (Section 24.16) that doesn't seem to have as many problems. But this article is worth reading anyway for what it shows you about process names and the ps command. It's good info to keep in mind when you're trying to kill processes in a hurry.

On my Linux system, the kill(1) manual page says I can send signals to processes either by PID numbers (as we showed in Section 24.12) or by process names. To an old stick-in-the-mud Unix user like me, who's been killing processes by their PIDs for 20 years, this doesn't seem very appealing. But hey, even I appreciate some of the new things Unix and Linux can do! `;-)` So we're saying that, if my system is slow and I want to temporarily stop the two gcc compiles I'm running in the background, I can just type:

>     $ kill -STOP gcc
>     [2]   Stopped            gcc -c bigprog.c sub1.c sub2.c ...
>     [4]-  Stopped            gcc -o something something.c

Not necessarily. This is not always as simple as it seems. For one, before you kill a process by name, you'd better be sure that there are no other processes by that name, owned by you, running at the same time -- unless you want to kill them too. That includes processes on other windows and ttys you're logged onto at the time; it also includes at, cron, or batch jobs that are running somewhere else on the system. Second, the process name may not be what you think it is. Third, even if your kill(1) manpage says that kill can do this, your shell may have a built-in kill that doesn't understand how to kill processes by name.

For example, let's say I have a runaway shell script named cruncher. I'm running it twice, and I want to kill both instances. Watch:

`&` Section 23.2

>     1$ cruncher & cruncher &
>     [1] 21451
>     [2] 21456
>     2$ kill cruncher
>     bash2: kill: cruncher: no such pid
>     3$ type -all kill
>     kill is a shell builtin
>     kill is /bin/kill
>     4$ /bin/kill cruncher
>     kill: can't find process "cruncher"
>     5$ jobs
>     [1]-  Running                 cruncher &
>     [2]+  Running                 cruncher &
>     6$ kill %1
>     [1]-  Terminated              cruncher
>     7$ ps
>        ...
>     21456 pts/1    00:01:25 cruncher
>     8$ ps x
>     21456 pts/1    S      1:33 sh /u/jerry/.bin/cruncher

In command 1, I put the two jobs in the background. In command 2, I try to kill them by name. But my shell, bash2, is complaining "no such pid." Hmmm; it's using the shell's built-in kill; the bash2 manpage seems to say that its kill only understands PID numbers. So, in command 3, I run type -all and find that the system kill is /bin/kill. In command 4, I give the process name again, but /bin/kill can't find it. Say what? Typing jobs, command 5, shows two crunchers running. And I can kill one of them by using its job number, in command 6. More confusing, running ps, in command 7, also shows cruncher running.

The story ends at command 8, where I ran the BSD version of ps (Section 24.5). It shows me what the default "friendly" System V-style ps (in command 7) didn't: the complete command line is actually `sh /u/jerry/.bin/cruncher`. This is a shell script, so the script filename cruncher, with the executable's directory from the PATH (Section 35.6) prepended, is passed to a shell as an argument (Section 27.3). So (whew): to kill these shell scripts, I should have typed `kill sh`. But do I really want to kill all running shells?

Another problem with killing a process by name is that a process can start a subprocess (Section 24.3) with a different name. For instance, if your make (Section 11.10) job starts a gcc compiler, and you type `kill make`, will that kill gcc too? Maybe -- if the signal that make gets is passed to its subprocesses (if its subprocesses haven't been disowned (Section 23.11), for instance). But unless all "smart" versions of kill are smarter than I think they are, they won't kill subprocesses with different names.

And don't think that you can just write an alias (Section 29.2) to override your shell's kill with /bin/kill: if you do, you won't be able to use job control (Section 23.1) numbers like `%1` because the external kill doesn't have access to your shell's job table.

My advice? It might be easier to use the old way -- running ps to find the process(es) and kill by PID number -- or use a script like zap (Section 24.16) instead.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.