BSD Newsletter.com
   Front | Info | Lists | Newsfeeds | Study Guide | What is BSD?
Advertisement: The OpenBSD PF Packet Filter Book: PF for NetBSD, FreeBSD, DragonFly and OpenBSD

BSD Links
·New Links
·Advocacy
·Drivers
·Events
·Flavours
·FAQs
·Guides
·Programming
·Security
·Software
·User Groups

This is the BSDA Study Guide Book written via a wiki collaboration. This is a work in progress. You may contribute to or discuss this specific page at http://bsdwiki.reedmedia.net/wiki/Use_job_control.html.

Use job control

Concept

  • Know how to:

    • start a process in the background
    • place an existing process into the background, and
    • return a background process to the foreground.
  • Be able to verify if any jobs are currently in the background.

  • Be aware of the difference between kill(1) and the shell built-in "kill".

Introduction

Some jobs run by the shell are "small jobs" --- quick and easy for the machine, with virtually no waiting for the user. Consider these small files and the use of grep(1):

$ ls -l
-rw-r--r--  1 myuser  wheel    315 Jan 19 13:00 notes.txt
-rw-r--r--  1 myuser  wheel   1967 Jan 18 13:49 otherstuff
-rw-r--r--  1 myuser  wheel   6335 Jan 11 23:11 packagelist
-rw-r--r--  1 myuser  wheel  14764 Jan 23 13:45 spammers
-rw-r--r--  1 myuser  wheel   2678 Jan 23 13:46 spamstuff.txt

$ grep speakeasy *
spammers:.dsl.speakeasy.net

The job is finished almost instantly, and your shell returns control to you. On the other hand, consider this:

# tar -c -z -f /backup/src.tar /usr/src/*

Depending on your system, it could take a very long time for you to make a gzipped archive of your BSD's project source tree! So, you can wait and twiddle your thumbs, or you can use job control to have the shell "put the job in the background" and return to your prompt so you can keep working.

Job Control

All modern shells feature job control. In the BSD's, the standard user's shell is csh/tcsh, but the information presented here should apply equally well to other shells, except as noted. The manpage for tcsh(1) has an entire section on job control, which should be read as an additional resource to clarify and extend this section.

TODO: fix this. csh/tcsh is NOT the standard shell for each BSD. TODO: And tcsh is not installed by default on each BSD

With a job-control shell, you can start a job so that it runs in the background, see information about currently running "backgrounded" jobs, move jobs from the foreground to background or vice-versa, or terminate them abruptly.

"Backgrounding" and "Foregrounding" jobs

The shell keeps a list of (backgrounded) jobs, including their status, which can be queried with the "jobs" shell built-in. If/when the job exits, the shell will report this, along with the job's exit status, prior to the next shell prompt.

Listing the process IDs (PID) with the jobs can be done with "jobs -l". (TODO: check shells)

To start a job in the background, end the command line with "&". To see running jobs, type "jobs" ("jobs -l" is also handy; many systems have "j" aliased to "jobs -l"). You can then use the job numbers in conjunction with "bg %" or "fg %" to move jobs from foreground to background and vice-versa.

If you start a long job in the foreground and then realize you forgot the "&", you can suspend the job with CTL-Z, then issue "bg" to the shell and the job will continue in the background. You might also use "kill -STOP" for suspend, and "kill -CONT" to continue; see below.

See the Examples section for details.

A word about "kill"

A job control shell usually has a built-in 'kill' command; a problem can ensue when this 'kill' is confused with kill(1).

For example, in the tcsh shell you should use a "%" sign to indicate a job number to the shell; otherwise it may be confused with a process ID in the system. While "kill %1" would simply terminate the first backgrounded job, "kill 1" would send a TERM signal to the process with PID 1 (usually /sbin/init!), and would have a similar effect to calling shutdown(8)! As a "normal" user, this would probably not be an issue, but if you were to do this as root, you might cause some problems. (Chalk this up as yet another reason not to do normal work as "root").

Most other shells also have a "kill" built-in. If you use another shell, try "type kill" at the prompt. If the shell doesn't answer "/bin/kill", then it will probably say something similar to "kill is a shell built-in". If your shell has a built-in kill, check your shell's manpage for details on using "kill" under your shell.

Redirecting job output

If you intend to use job control it is useful to know about output redirection, because, under most circumstances, jobs that produce output will continue to do so, potentially "cluttering up" your terminal and whatever your "next project" is. See section Demonstrate proficiency in using redirection, pipes and tees for details.

Examples

$ sh ~/scripts/mylongscript.sh &
sh /home/myuser/scripts/mylongscript.sh &
[1] 10394

Execute "mylongscript.sh" in the background. The shell reports the command, the job number, and the job's PID on the system.

$ tar -c -f /backup/src.tar /usr/src/*
tar: Removing leading '/' from member names

Oops! There's that long job again, and we forgot to background it. While "stuck" waiting, press Ctrl-Z:

^Z
Suspended

Now you have your prompt back, so issue "bg":

$ bg
[2]    tar -c -f /backup/src.tar /usr/src/COPYRIGHT /usr/src/LOCKS  ... &

Now run "jobs" and you should see both "backgrounded" tasks in the list:

$ jobs
[1]  + Running     sh /home/myuser/scripts/mylongscript.sh &
[2]  - Running     tar -c -f /backup/src.tar /usr/src/COPYRIGHT /usr/src/LOCKS  ... &

But wait! Suppose a colleague is already making an archive of the source tree, so we don't need to.

$ fg 2
tar -c -f /backup/src.tar /usr/src/COPYRIGHT /usr/src/LOCKS  ... &
^C

A quick Ctrl-C, and we save lots of CPU cycles, and disk space, too. Of course, in csh/tcsh, we could have just called "kill" and obtained the same basic result:

$ kill %2

Practice Exercises

  1. Find a "long" job that needs to be run, and do it in the background with "&". (Optionally, use redirection to make sure any output goes to a file or to the "bit-bucket".)

  2. Call the job to the foreground, then terminate it with CTL-C. (Do this fairly early!)

  3. Start the job again in the foreground, then use CTL-Z to suspend the job. Then issue "bg".

  4. While the job (possibly more) is running, call "jobs" and then "jobs -l" (or "jobs -ls" in some shells). Study the differences in the output.

  5. Use kill to terminate the job. Remember that in some shells, you must use "%" ("kill %1"). In others, it may be necessary to obtain the job's PID (which can be done with "jobs -l", or other tools) and use this as a flag to kill(1).

More information

\&, CTRL-Z, jobs, bg, fg, and "kill" which are all built-in to the shell



Front | Information | Lists | Newsfeeds