1. Overview

Killing a stopped job or process is not a difficult task. Usually, we just need to call the kill command with the process ID (PID). However, sometimes Linux may hide the processes depending on which terminal launched them and whether they have higher privileges.

In this tutorial, we’ll discuss how to target and kill these processes in different scenarios using several commands.

2. Killing All Stopped Jobs From the Same Terminal

It’s rather easy to kill stopped processes launched from the same terminal. All we need to do is find the process IDs of the jobs and then send the SIGKILL signal to them.

For example, we can use the sleep command to initiate a task that does nothing:

$ sleep 1m

This program will occupy the terminal for 1 minute. After running the command above, we interrupt it using CTRL+Z to send the SIGTSTP signal:

$ sleep 1m
[1]+  Stopped                 sleep 1m

Now, we have a stopped job. Next, we can use the jobs command to list that job:

$ jobs -p -s

Here, we use –p for getting the process ID, while –s filters only for processes that are stopped.

Additionally, we can use the -l parameter instead of -p for a more detailed view of the stopped job:

$ jobs -ls
[1]+  4772  Stopped                 sleep 1m

The jobs -ls command will show all the stopped jobs launched in this session. Once we find their process IDs, we can use the kill command to stop all of them by providing multiple process IDs to the kill command, or we can directly pipe the jobs command after the kill command like this:

$ kill -9 `jobs -ps`

Importantly, it’s best to use the SIGKILL, not the SIGTERM signal, as code can easily catch or block the latter.

3. Killing All Stopped Jobs From Another Terminal

Sometimes we don’t have direct access to the terminal running a particular job. In these cases, it’s convenient to have a mechanism to identify and stop such jobs.

Linux does not let us see a terminal-launched process from another terminal with the jobs command. Because of this, we’ll use the ps command instead.

Let’s create two instances of the previously described process first:

$ tty
$ sleep 1m
[1]+  Stopped                 sleep 1m
$ sleep 2m
[2]+  Stopped                 sleep 1m
$ bg
[2]+ sleep 2m &

Note the use of tty to show the terminal we’re using. Further, we use bg to ensure that only the first job is stopped while the last one is running in the background.

We can use the ps command in another terminal to see the newly created jobs. In fact, the flags aux ensure we see all processes (a) under the current user (u) with their states (x):

$ tty
$ ps aux | grep [s]leep
username        5767  0.0  0.0   2364   572 pts/0    T    15:23   0:00 sleep 1m
username        5768  0.0  0.0   2364   580 pts/0    S    15:24   0:00 sleep 2m

Of course, we can filter by process name with grep. Furthermore, to identify the correct process, we need to pay attention to the STAT column, holding the current state of a process. Critically, T stands for “stopped by a job control signal”, which means it’s a stopped job of a terminal.

The output above shows that we have stopped process 5767 while process 5768 is still running. Now, we use the awk language to filter only those jobs:

$ tty
$ ps aux | awk {'if ($8 ==  "T") print $2" "$8" "$11'}
5767 T sleep 1m

Above, we only use rows of output, where column 8 ($8, STAT) has a value of T. From those rows, we extract the process ID, STAT, and actual command run via $2″ “$8” “$11. Of course, it’s easy to only print $2 for the PID. This awk expression will show us all the stopped jobs as a list.

Finally, we can kill all processes of interest by piping our output from ps to kill:

$ tty
$ kill -9 `ps aux | awk {'if ($8 == "T") print $2'}`

We can verify the correct processes have been killed in the original terminal:

$ tty
$ jobs
[1]+  Killed                  sleep 1m
[2]-  Running                 sleep 2m &

As the jobs command tells us, we have successfully killed only the stopped processes in another terminal.

4. Conclusion

In this article, we briefly covered how to kill all stopped jobs under different circumstances. First, we used the jobs command to identify local terminal processes. After that, we employed ps to help with specific cases.