How to Control Processes in Linux using bg, fg and jobs Commands

Describing Jobs and Sessions

Job control is a feature of the shell which allows a single shell instance to run and manage multiple commands. A job is associated with each pipeline entered at a shell prompt. All processes in that pipeline are part of the job and are members of the same process group. If only one command is entered at a shell prompt, that can be considered to be a minimal “pipeline” of one command, creating a job with only one member.

Only one job can read input and keyboard generated signals from a particular terminal window at a time. Processes that are part of that job are foreground processes of that controlling terminal. A background process of that controlling terminal is a member of any other job associated with that terminal. Background processes of a terminal cannot read input or receive keyboard generated interrupts from the terminal but may be able to write to the terminal. A job in the background may be stopped (suspended) or it may be running. If a running background job tries to read from the terminal, it will be automatically suspended.

Each terminal is its own session and can have a foreground process and any number of independent background processes. A job is part of exactly one session: the one belonging to its controlling terminal. The ps command shows the device name of the controlling terminal of a process in the TTY column. Some processes, such as system daemons, are started by the system and not from a shell prompt. These processes do not have a controlling terminal, are not members of a job, and cannot be brought to the foreground. The ps command displays a question mark (?) in the TTY column for these processes.

Running jobs in the background

Any command or pipeline can be started in the background by appending an ampersand (&) to the end of the command line. The Bash shell displays a job number (unique to the session) and the PID of the new child process. The shell does not wait for the child process to terminate, but rather displays the shell prompt.

[user@host ~]$ sleep 10000 &
[1] 5947
[user@host ~]$
 [user@host ~]$ example_command | sort | mail -s "Sort output" &
[1] 5998

You can display the list of jobs that Bash is tracking for a particular session with the jobs command.

[user@host ~]$ jobs
[1]+ Running sleep 10000 &
[user@host ~]$

A background job can be brought to the foreground by using the fg command with its job ID (%job number).

[user@host ~]$ fg %1
sleep 10000

In the preceding example, the sleep command is now running in the foreground on the controlling terminal. The shell itself is again asleep, waiting for this child process to exit. To send a foreground process to the background, first press the keyboard generated suspend request (Ctrl+Z) in the terminal.

sleep 10000
[1]+ Stopped sleep 10000
[user@host ~]$

The job is immediately placed in the background and is suspended. The ‘ps j’ command displays information relating to jobs. The PID is the unique process ID of the process. THe PPID is the PID of the parent process of this process, the process that started (forked) it. The PGID is the PID of the process group leader, normally the first process in the job’s pipeline. The SID is the PID of the session leader, which (for a job) is normally the interactive shell that is running on its controlling terminal. Since the example sleep command is currently suspended, its process state is T.

[user@host ~]$ ps j
2764   2768   2768   2768   pts/0   6377    Ss     1000   0:00   /bin/bash
2768   5947   5947   2768   pts/0   6377    T      1000   0:00   sleep 10000
2768   6377   6377   2768   pts/0   6377    R+     1000   0:00   ps j

To start the suspended process running in the background, use the bg command with the same job ID.

[user@host ~]$ bg %1
[1]+ sleep 10000 &

The shell will warn a user who attempts to exit a terminal window (session) with suspended jobs. If the user tries exiting again immediately, the suspended jobs are killed.