1. Overview

Linux provides several commands to end or kill processes. Although similar in the underlying system call they use, each one has its own advantages.

In this short tutorial, we’ll see the benefits of each command, along with examples where each one excels.

2. What Is the kill System Call?

On Linux, a system call is an interface to access kernel functionality. Low-level tasks can be performed by asking the kernel to do them for us.

To end processes, we can use the kill system call. It takes two arguments: the process ID and the signal to send when killing the process.

A signal indicates the reason for killing the process. It’s composed of a name and a related number. The process will respond differently depending on the signal it receives. There are many signals we could send a process we’re killing, but let’s see a few that are the most popular.

We could send signal SIGTERM (15) or SIGINT (2) to ask the process to shut down gracefully. The process can ignore this request.

We could send SIGKILL (9) or *SIGSTOP (*19), which cannot be ignored. SIGKILL forces the process to terminate, while SIGSTOP pauses it.

In this tutorial, we’ll focus on terminating processes, but thanks to signals, we could use the kill call more broadly. For instance, we could pause and resume processes, or cause them to reload their configuration.

Let’s now see how commands use this system call.

3. kill

The kill command is the simplest wrapper of the system call. It requires the process ID and, by default, sends the SIGTERM signal to the process. To use it, we need to first find the process ID with the ps command:

$ ps x
   PID TTY      STAT   TIME COMMAND
...
  15709 pts/0    Ss     0:00 bash
  16299 ?        Sl     0:00 /usr/bin/gedit --gapplication-service
  16405 pts/0    R+     0:00 ps x

Let’s suppose we want to terminate gedit. We could execute the following command:

$ kill 16299

If we would like to be sure it’s terminated, we could pass in SIGKILL:

$ kill -9 16299
# Or by signal name kill -SIGKILL 16299

The kill command is straightforward. We only need to find the PID to use it. This is an advantage because if the PID does not exist, the command will return an error.

4. pkill

In most cases, when we want to terminate a process, we also know its name. This is why pkill is so useful. We can now kill the gedit process by using its name:

$ pkill gedit

This command takes a pattern as the only required argument. That pattern will be matched against all process names, and the matching processes will be terminated. This also is a double-edged sword, as we could terminate processes we have no intention of terminating.

It is a good idea to check the processes that match the pattern first. We can use pgrep for that:

$ pgrep -a gedit
16299 /usr/bin/gedit --gapplication-service

Now we can use pkill confidently.

As with the kill command, the default signal to be sent is SIGTERM. We could force termination with:

$ pkill -9 gedit

There are other interesting things we can do with pkill. For example, we can restrict the search to processes that belong to specific users:

$ pkill -u myuser,otheruser gedit

Or kill all processes except the ones that match:

$ pkill -u myuser --inverse gedit

5. killall

Lastly, killall is another useful command. By default, it will only terminate processes that exactly match the name argument. For example, this command won’t find any process:

$ killall gedi

But the same argument would work if we were using pkill. This is a definite advantage if we know the name of the process and want to avoid killing processes we’ve matched unintentionally.

Like the other commands, this one also accepts a signal as an argument, like -SIGKILL or -9. Similar to kill, this command will return an error if no process matches the argument.

As with the pkill command, we can also terminate all processes of an individual user with:

$ killall -u otheruser

Two characteristics make killall unique. First, we can execute it interactively to confirm we found the right process:

$ killall -i gedit
Kill gedit(16299) ? (y/N)

Secondly, we can terminate a process based on the time it started. For instance, to terminate all gedit processes started an hour ago or before, we can run:

$ killall -i --older-than 60m gedit
Kill gedit(16299) ? (y/N)

Or we can terminate all gedit processes started in the last 2 hours:

$ killall -i --younger-than 2h gedit
Kill gedit(16299) ? (y/N)

6. Conclusion

In this short tutorial, we’ve seen how to use kill, pkill, and killall to terminate a process. There are subtle differences between the three, though, and understanding them will help us choose the right tool for the job.