Bash Job Controlor


Job control is a really useful part of bash. You can suspend and resum processes with it without breaking them.
So let's take a look at what this exactly is.


Jobs in bash

First off we need to list current jobs. Jobs are tied to their parent terminal (or bash to be exact), so each terminal can only see jobs created by themselves. To list the created jobs type:
jobs if it gives back an empty response, that means there are no jobs in that terminal. If you do have jobs it will give back something like:

[1]+ Stopped                         locate *.png

where:

  • [1] is the ID of that job
  • Stopped is the state of that job
  • locate *.png is the command

Creating jobs

There are several ways you can create a job, we'll discuss 2 of them

1. Suspending a process

If there is a long running process, you can press CTRL + Z and the process becomes suspended. It will be added to the jobs list, with the stopped state. From here you can use fg to return the process to the foreground, or bg to bring the process to the background. After you do that the job will be in Running state. When it finishes it will be in Done state.

2. Starting process in background

Let's take the locate *.png command and start it in the background like:
locate *.png & the & sign starts the process by default in the background and adds it to the jobs list, with Running state

Switching the context of jobs.

You can bring foreground processes to background, and background processes to foreground.
First find the ID of the job by jobs and look at the number for example:[1].
Now simply type fg %1 to bring the process ot the foreground and bg %1 to bring the process to the background.
% means that we're refering to the ID of a job.

Killing a job

If you don't want to wait for the job to exit, you can kill it manually.
Using the kill command with the same parameters as before like:
kill %1 to kill the first job in that list, this will set the job in Terminated state.
Another option is to bring the process to the foreground and then use the regular CTRL + C combination.

Dealing with SIGHUP

SIGHUP is sent to the terminal's jobs, when the terminal is about to close.
This will affect our background jobs and they will stop. However we can do something about that.

nohup

nohup ignores SIGHUPs and keeps the background job running until another signal like SIGKILL or SIGTERM is sent to the process/job. You can use nohup like so:
nohup ping youtube.com &, this will create a new job starting the nohup process, and nohup ignores the SIGHUP, while it executes the given command. But this is only an option when you know at the starting of the process that you're going to close the terminal. If you don't know it, there's an option for you too!

disown

Disown achives the same as nohup, but it can do it while a job is started. To do this, get the ID of your job and type:
disown -h %1
Disown by default removes the job from the job control, and we don't want to do that until the terminal closes. The -h option solves exactly this, it only removes the job from the job control when a SIGHUP is detected.
Impotant: If the output of the process isn't redirected to a file for example, then the output of the process will get lost when you close the terminal.
Note: To stop a job that's not listed on the job control, you need to locate the PID of that job an use kill [PID] to terminate it.

Summary

Job control is a powerful feature in bash, for example if you have an application, that blocks the input (a server application not running as a daemon) you can press CTRL + Z and type bg to get back your prompt and keep the server alive. You can also use disown to keep the server alive after closing the terminal.
Now go suspend some processes and background them!


Sources

nohup's Man Page
Bash's Man Page

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now