Chapter 3. background jobs

Table of Contents

background processes
jobs
control-Z
& ampersand
jobs -p
fg
bg
practice : background processes
solution : background processes

background processes

jobs

Stuff that runs in background of your current shell can be displayed with the jobs command. By default you will not have any jobs running in background.

root@rhel53 ~# jobs
root@rhel53 ~#
		

This jobs command will be used several times in this section.

control-Z

Some processes can be suspended with the Ctrl-Z key combination. This sends a SIGSTOP signal to the Linux kernel, effectively freezing the operation of the process.

When doing this in vi(m), then vi(m) goes to the background. The background vi(m) can be seen with the jobs command.

[paul@RHEL4a ~]$ vi procdemo.txt

[5]+  Stopped                 vim procdemo.txt
[paul@RHEL4a ~]$ jobs
[5]+  Stopped                 vim procdemo.txt
		

& ampersand

Processes that are started in background using the & character at the end of the command line are also visible with the jobs command.

[paul@RHEL4a ~]$ find / > allfiles.txt 2> /dev/null &
[6] 5230
[paul@RHEL4a ~]$ jobs
[5]+  Stopped                 vim procdemo.txt
[6]-  Running                 find / >allfiles.txt 2>/dev/null &
[paul@RHEL4a ~]$
		

jobs -p

An interesting option is jobs -p to see the process id of background processes.

[paul@RHEL4b ~]$ sleep 500 &
[1] 4902
[paul@RHEL4b ~]$ sleep 400 &
[2] 4903
[paul@RHEL4b ~]$ jobs -p
4902
4903
[paul@RHEL4b ~]$ ps `jobs -p`
  PID TTY      STAT   TIME COMMAND
 4902 pts/0    S      0:00 sleep 500
 4903 pts/0    S      0:00 sleep 400
[paul@RHEL4b ~]$
		

fg

Running the fg command will bring a background job to the foreground. The number of the background job to bring forward is the parameter of fg.

[paul@RHEL5 ~]$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 2000 &
[paul@RHEL5 ~]$ fg 3
sleep 2000
		

bg

Jobs that are suspended in background can be started in background with bg. The bg will send a SIGCONT signal.

Below an example of the sleep command (suspended with Ctrl-Z) being reactivated in background with bg.

[paul@RHEL5 ~]$ jobs
[paul@RHEL5 ~]$ sleep 5000 &
[1] 6702
[paul@RHEL5 ~]$ sleep 3000

[2]+  Stopped                 sleep 3000
[paul@RHEL5 ~]$ jobs
[1]-  Running                 sleep 5000 &
[2]+  Stopped                 sleep 3000
[paul@RHEL5 ~]$ bg 2
[2]+ sleep 3000 &
[paul@RHEL5 ~]$ jobs
[1]-  Running                 sleep 5000 &
[2]+  Running                 sleep 3000 &
[paul@RHEL5 ~]$ 
		

practice : background processes

1. Use the jobs command to verify whether you have any processes running in background.

2. Use vi to create a little text file. Suspend vi in background.

3. Verify with jobs that vi is suspended in background.

4. Start find / > allfiles.txt 2>/dev/null in foreground. Suspend it in background before it finishes.

5. Start two long sleep processes in background.

6. Display all jobs in background.

7. Use the kill command to suspend the last sleep process.

8. Continue the find process in background (make sure it runs again).

9. Put one of the sleep commands back in foreground.

10. (if time permits, a general review question...) Explain in detail where the numbers come from in the next screenshot. When are the variables replaced by their value ? By which shell ?

[paul@RHEL4b ~]$ echo $$ $PPID
4224 4223
[paul@RHEL4b ~]$ bash -c "echo $$ $PPID"
4224 4223
[paul@RHEL4b ~]$ bash -c 'echo $$ $PPID'
5059 4224
[paul@RHEL4b ~]$ bash -c `echo $$ $PPID`
4223: 4224: command not found

solution : background processes

1. Use the jobs command to verify whether you have any processes running in background.

jobs (maybe the catfun is still running?)

2. Use vi to create a little text file. Suspend vi in background.

vi text.txt
(inside vi press ctrl-z)

3. Verify with jobs that vi is suspended in background.

[paul@rhel53 ~]$ jobs
[1]+  Stopped                 vim text.txt

4. Start find / > allfiles.txt 2>/dev/null in foreground. Suspend it in background before it finishes.

[paul@rhel53 ~]$ find / > allfiles.txt 2>/dev/null
   (press ctrl-z)
[2]+  Stopped                 find / > allfiles.txt 2> /dev/null

5. Start two long sleep processes in background.

sleep 4000 & ; sleep 5000 &

6. Display all jobs in background.

[paul@rhel53 ~]$ jobs
[1]-  Stopped                 vim text.txt
[2]+  Stopped                 find / > allfiles.txt 2> /dev/null
[3]   Running                 sleep 4000 &
[4]   Running                 sleep 5000 &

7. Use the kill command to suspend the last sleep process.

[paul@rhel53 ~]$ kill -SIGSTOP 4519
[paul@rhel53 ~]$ jobs
[1]   Stopped                 vim text.txt
[2]-  Stopped                 find / > allfiles.txt 2> /dev/null
[3]   Running                 sleep 4000 &
[4]+  Stopped                 sleep 5000

8. Continue the find process in background (make sure it runs again).

bg 2 (verify the job-id in your jobs list)

9. Put one of the sleep commands back in foreground.

fg 3 (again verify your job-id)

10. (if time permits, a general review question...) Explain in detail where the numbers come from in the next screenshot. When are the variables replaced by their value ? By which shell ?

[paul@RHEL4b ~]$ echo $$ $PPID
4224 4223
[paul@RHEL4b ~]$ bash -c "echo $$ $PPID"
4224 4223
[paul@RHEL4b ~]$ bash -c 'echo $$ $PPID'
5059 4224
[paul@RHEL4b ~]$ bash -c `echo $$ $PPID`
4223: 4224: command not found
	

The current bash shell will replace the $$ and $PPID while scanning the line, and before executing the echo command.

[paul@RHEL4b ~]$ echo $$ $PPID
4224 4223
	

The variables are now double quoted, but the current bash shell will replace $$ and $PPID while scanning the line, and before executing the bach -c command.

[paul@RHEL4b ~]$ bash -c "echo $$ $PPID"
4224 4223
	

The variables are now single quoted. The current bash shell will not replace the $$ and the $PPID. The bash -c command will be executed before the variables replaced with their value. This latter bash is the one replacing the $$ and $PPID with their value.

[paul@RHEL4b ~]$ bash -c 'echo $$ $PPID'
5059 4224
	

With backticks the shell will still replace both variable before the embedded echo is executed. The result of this echo is the two process id's. These are given as commands to bash -c. But two numbers are not commands!

[paul@RHEL4b ~]$ bash -c `echo $$ $PPID`
4223: 4224: command not found