1. Overview

The job control feature in Linux enables users to manage and control running processes efficiently. However, there may be instances when we need to cancel or delete a job that’s currently running in the background or in a separate terminal session.

In this tutorial, we’ll go through the process of canceling or deleting a job in Linux in regular as well as extraordinary conditions. In addition, we’ll look at code snippets along with output examples, and discuss any necessary command options.

2. Deleting Normal Jobs

To check the running jobs in our Linux system, we’ll utilize the jobs command:

$ jobs
[1]+  Running                 sleep 300 &

The jobs command lists all jobs on the system. In essence, it returns non-deleted jobs in a running or paused state. In detail, jobs are shell child processes running in the background or foreground.

The output of the previous example shows that there’s one job in a Running state with job ID 1. Moreover, the & symbol enables commands to run as background processes, allowing the shell to promptly return for the execution of subsequent commands. F

Let’s check out how to kill a job:

$ kill %1
[1]+  Terminated              sleep 300

We use the kill command to terminate running jobs. To terminate a specific job using kill, we provide the job ID as an argument to the command. Furthermore, the % symbol is prepended to indicate that what follows is the job ID to be killed. Finally, number 1 indicates the actual job ID.

Accordingly, we see that the status of the job has turned from Running to Terminated, indicating the successful operation of killing the job.

3. Finding and Force-Killing a Job

After getting to know jobs, let’s see how to find and forcibly kill a specific job that’s unresponsive or not terminating gracefully on its own:

$ find / -name "huge_file" > output.txt &
[1] 1234

This find command searches for a file named huge_file in the root directory / and its subdirectories. In particular, we use the -name option to indicate that what follows will be the file name. Moreover, the > symbol redirects the output of the command to the output.txt file. Finally, the & symbol at the end of the command places the command in the background, enabling us to continue using the terminal while the command is executing.

In the above example, the output shown by the shell indicates that the command started in the background and was assigned a job ID of 1 with a process ID (PID) of 1234.

At this point, let’s list the jobs currently running on our system:

$ jobs
[1]+  Running                 find / -name "huge_file" > output.txt &

In this case, the output shows the job ID, status, and the command. As expected, the job ID is 1, while the status of the job is Running.

Let’s suppose the job has been running for too long. To force-kill the job, we can use the kill command with the -9 option and the job ID, 1:

$ kill -9 %1
[1]+  Killed                  find / -name "huge_file" > output.txt

Notably, the -9 option with kill should be used as a last resort, as it forcefully terminates the process without allowing it to perform any cleanup tasks. In other words, we use kill -9 or kill -SIGKILL only when a process is unresponsive or not terminating gracefully.

4. Using pgrep and pkill

In this section, we’ll use the pgrep and pkill commands to find and delete jobs based on their process names:

$ sleep 600 &
[1] 1234
$ sleep 900 &
[2] 5678

In the previous example, there are two job IDs, 1 and 2, with their respective PIDs 1234 and 5678.

To find the PID of a specific job, we use the pgrep command:

$ pgrep sleep
1234
5678

This is a real-life example of how to use the pgrep command to get the PIDs by using the name of the job as an argument. In our case, we used sleep as the argument to pgrep, which printed out the PIDs of both jobs we listed.

After having it, let’s check out how to delete a job based on its process name:

$ pkill sleep
[1]-  Terminated              sleep 600
[2]+  Terminated              sleep 900

We use the pkill command in combination with sleep as an argument. The output shows the new status of both jobs changed to Terminated.

Nevertheless, this approach may lack accuracy as it could lead to locating or terminating processes that only partially match the given criteria or processes that are unrelated to the job management system.

5. Using the qstat Command in GridEngine

The qstat command isn’t a built-in command in Linux, but rather a command used in some specific job-scheduling systems, such as Sun Grid Engine. Thus, we’d need the latter already installed on the system beforehand.

First, let’s install qstat to use it with the Sun Grid Engine (SGE):

$ sudo apt install gridengine-client gridengine-qmon

In this case, we use apt to install the gridengine-client package, which includes qstat and gridengine-qmon for the graphical monitoring tool.

To ensure proper installation of the package, we utilize dpkg:

$ dpkg --get-selections | grep -w "install" | head 
acl                                   install 
qstat                                 install

The output above is a list of packages as returned by the –get-selections option. Additionally, we used a pipe to direct the output to a grep command, which filters and selects only the lines containing the word install.

At this point, we can use the qstat command to display information about jobs in the scheduling system:

$ qstat
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
   1234 0.00000 sleep.sh   john.doe     qw    06/10/2023 14:30:00                                    1
   5678 0.00000 bash.sh    jane.doe     r     06/11/2023 09:45:00                                    1

Let’s check out how to kill a specific job in this case:

$ qdel 5678
$ qstat
job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID
-----------------------------------------------------------------------------------------------------------------
   1234 0.00000 sleep.sh   john.doe     qw    06/10/2023 14:30:00                                    1

In the provided example, the qdel command is used with the job ID 5678 specifying the job to be deleted. Accordingly, the output of qstat shows the successful deletion of the job with job ID 5678.

6. Conclusion

In this article, we discussed finding and deleting jobs using commands like jobs, kill, and force killing unresponsive jobs using the -9 option in the kill command.

Moreover, we discussed the use of pgrep, pkill, and even qstat in specific scenarios. These techniques provide us with efficient tools to handle and control jobs in our Linux systems effectively.