[Next] [Previous] [Up] [Top] [Contents] [Index]

Chapter 5: Important UNIX Concepts

5.5 Job Control

Any command you give to the shell (true for all shells except sh) is a job and is given a job number. A single command is the simplest job. A series of commands separated by semicolons, or commands piped together, create a single job. A script also creates a single job. A job may consist of many processes, because each command is a process.

The job stays with its environment, for example, the current directory. If you subsequently change directories after putting a job in the background and then resume the background job, you will be in the original directory again.

Job control allows you to work on several jobs at once, switching back and forth between them at will, and it allows you to stop, start, and kill them. When you start up a job interactively, it is by default in the foreground and attached to your terminal. You can move that job into the background so you can start up another job or observe another job that is already running. You can move any background job into the foreground so it is once again attached to your terminal. You can run any number of background jobs at any one time, but there can be only one foreground job. The use of multiple windows on an X terminal makes much of this transparent.

5.5.1 Priority

You can control the priority of a command or shell with the shell command nice:

% nice [+n |-n] [command] 

n is the value by which you want to increase or decrease priority. Values range from 1 to 19, with the default at 10. The higher the nice value, the lower the priority of a process, and the slower it runs. (You are being nicer to other users!) If no number is specified, nice sets the priority to 4. If command is omitted, the priority is set for the current shell. If command is specified, it is run at the specified (or default) priority in a sub-shell. You can use nice to lower the priority of a command or shell that makes large demands on the system but isn't needed right away.

Note that another nice command exists, /bin/nice. It is not a built-in shell command. If you do man nice, you will get information on this one. In order to get information on the shell command nice, do man csh (using csh as an example).

5.5.2 Background, Foreground, and Suspended Jobs

You run jobs in the background so that you can perform other tasks in the foreground (i.e., interactively). Jobs are always in one of three states: running in the foreground, running in the background, or suspended. Any job intended to run in the background should have its output and error redirected to a file.

There are two ways to put jobs into the background:

Using the & Metacharacter

One way to start a job in the background is to append the ampersand metacharacter (&) to the end of the command line. In the first example, the standard output is redirected to a file (in this case, the syntax is valid for both shell families):

% command > output-file & 

Note that the parentheses are necessary in the next example in order to send both commands to the background:

% (command1; command2) & 

The shell prints a line indicating the job number and process ID of its top-level commands, and the job is started as a background job.

Using the Suspend Control Character

The other way is to use the suspend control character, called susp or swtch, (see section 2.4) which is usually assigned to <Ctrl-z>. It stops or suspends the foreground (the currently running interactive) job, moving it to the background; it does not kill it.

After stopping a job, you can either resume it with the fg command or make it run in the background with the bg command (see below). You may want to stop a job temporarily to do another task and then return to it interactively, or you may want to stop it in order to let it finish as a background job.

When a background job terminates, this is reported just before the next prompt (so the message doesn't interrupt the current foreground job).

A background job will stop if it tries to read from the terminal. If output is not redirected, a background job can either (continue to) send output to the terminal or be stopped if it attempts to write to the terminal. The following command can be used to toggle this behavior:

% stty [-]tostop 

The minus indicates negation, meaning that background jobs will continue to run even if they attempt to write output to the terminal and that the output will appear on the terminal screen. However, programs which attempt to interrogate or change the mode of the terminal will be blocked when they are not in the foreground whether or not tostop is set.

Listing Jobs

The jobs command lists your jobs:

% jobs [-l] 

This command lists the background jobs, their job number, status, and the command being executed. A plus sign in the output means that job is current (in control of your terminal), a minus sign means that job is next. Current and next refer to its relation to the foreground (see fg). The -l option lists the process ID as well.

Commands Used for Controlling Jobs

There are a number of commands to control jobs: fg, bg, stop, kill. All of them can take an argument which specifies the particular job, or they can have no argument. The argument can take two basic forms: a simple process ID number (as displayed by ps) or a form prefixed with a percent sign (%). If no argument is given, the current job is acted upon.

The % form of the argument can be %- where - indicates the previous job, %n where n is the job number as displayed by the jobs command, %pref where pref is some unique prefix of the command name and arguments of one of the jobs, or %?str where str is some unique string in one of the jobs.

You can use the fg command to move a suspended or background job into the foreground:

% [fg] %[job] 

The fg is not mandatory. If the job specification is omitted, the current job will be brought into the foreground, and the next job becomes current.

Examples (note that the first % on each line represents the default csh prompt):

% fg %5

Bring job number 5 into the foreground

% %1

Bring job number 1 into the foreground

% %

Bring the current job into the foreground

After stopping a foreground job, you can start it running in the background with the bg command. bg puts the current or specified jobs into the background, continuing them if they were stopped. In the following commands, job stands for job number.

% bg %[job] 

We described above how to stop (suspend) a foreground job with the suspend control character (<Ctrl-z>). Similarly, you can suspend a background job with the stop command:

% stop %job 

You can abort a suspended or background job with the kill command:

% kill %job 

If you attempt to exit a shell (logout) when there are stopped jobs, you will get a warning message. A second logout will log you out if you choose not to see what jobs are stopped before you exit. In the C shell family, background jobs will continue running after you log out.

5.5.3 Scheduling Jobs: at and cron

UNIX provides two methods for running jobs at some specified time.

If AFS is installed on your system, there are Kerberos authentication problems with running programs that spawn jobs external to your login process group (Kerberos authentication is described in section 7.3). at and cron fall into this category. You can run the job, but it will not run with authentication, and most likely will not be able to write into /afs space. A work-around is available for executing an authenticated cron job (send mail to helpdesk@fnal requesting the full details of this procedure).

at

The first is the at utililty. This allows the user to queue a job for later execution.

The format of the at command is:

% at time [date] [+increment] 

at reads the commands from standard input. Standard output and standard error output will be mailed to you unless they are redirected.

The shell saves the environment variables and the working directory that are in effect at the time you submit the job and makes them available when the job is executed.

Examples:

% at 8 
% at 0800 
% at 8:00am Jan 24 
% at now + 1 minute 

at reads from standard input, meaning you type in the commands (there may or may not be a prompt). When you are finished, terminate input with <Ctrl-d> followed by a carriage return.

You can also redirect the input to a file of commands, for example:

% at now + 1 hour < myscript

at runs in the Bourne shell (sh) by default. If you need to force it to run in C shell, you can use the trick illustrated in the following interactive example:

% /bin/csh << xxxxx
? at now + 2 minutes
? source .cshrc
? alias > aout
? <Ctrl-d> (followed by carriage return)

The first line causes csh (C shell) to read the following lines up to xxxxx or to the end-of-file. There is no xxxxx, of course, so it reads until you give it the <Ctrl-d>. The third line runs your .cshrc. It is an illegal Bourne shell command, therefore you can tell at ran in the C shell and that your .cshrc file was executed. You will receive a message similar to the following, and the results will be mailed to you (alas, at will say it's using /bin/sh even if you've "tricked" it):

warning: commands will be executed using /bin/sh
job 826157640.a at Wed Mar  6 18:14:00 1996

After 2 minutes, aout is mailed to you. It contains a list of all the aliases defined in your .cshrc file. If you are running a script using at then the script will be run under whatever shell you specify in the script.

For example, say you run:

% at now + 2 minutes
? script
? <Ctrl-d> (followed by carriage return)

where script is a file that contains the line #!/bin/csh at the beginning. The commands in the script will execute under csh.

cron

The second method for running jobs at some specified time is the crontab command. It is designed for jobs that need to be run on a regular basis, e.g., once a night, or once per week. Note that cron, like at, uses the Bourne shell so that output redirection must be specified using Bourne shell syntax. Scripts will be run under what ever shell is specified in the script. If no shell is specified then Bourne shell is used.

The format of the command is:

% crontab [filename]
% crontab [options]

where filename is the name of a file containing the commands that you want to have executed. If you do not specify a file, then crontab will read commands from standard input as you type them, ending with <Ctrl-d>, and the commands will be run in Bourne shell. The system utility cron reads the crontab file and runs the commands. Standard output and standard error will be mailed to you unless they are redirected.

The command can also take the following options:

-r remove crontab file

-l list contents of crontab file

A cron file consists of lines of six fields each. The fields are separated by spaces or tabs. The first five are integer patterns that specify the following:

If an asterisk appears in a field instead of a number, cron interprets that as a wildcard for all possible values. The sixth field of a line in a cron file is a string that is executed by the shell at the specified times.

Examples:

The user creates a cron file myfile, and runs crontab:

#Myfile

# Run script that archives to 8mm tape for backup.

# Monday-Thursday at 2200 backup everything that has been

# changed. Every Friday at 2200 backup everything.

0 22 * * 1-4 /usr/buckley/daily 1>>/usr/buckley/cron/backup.log 2>&1

0 22 * * 5 /usr/buckley/weekly 1>>/usr/buckley/cron/backup.log 2>&1

% crontab myfile

This command will perform an incremental backup at 10pm Monday to Thursday and a full backup at 10pm on Friday.


UNIX at Fermilab - 10 Apr 1998

[Next] [Previous] [Up] [Top] [Contents] [Index]