Background Jobs and I/O
Jobs being executed in the background will stop if they attempt to read input from your terminal. If you tried to interactively remove
$PUBDIR/junk
in the background, this is what would happen:
$ rm i $PUBDIR/junk &
[2] +Stopped (tty input) rm i $PUBDIR/junk &
The job is stopped because it needs to prompt you for input. The
rm -i
job is brought back into the foreground with the
fg
command and its prompt is displayed:
$ fg %2
rm i $PUBDIR/junk
rm: remove /usr/spool/uucppublic/junk? y
By default, jobs send their output to your terminal, even while running in the background. Here, the
find
command sends its output to the terminal, even though it is running in the background:
$ find / name core print &
[2] 1453
$ /usr/lbin/core
/home/anatole/bin/core
That can be annoying,
especially
if you are in the middle of something else. To avoid this problem, redirect the output of background jobs to a file. Make sure to be careful with the redirection. If you don't redirect standard error, error messages will go to your terminal and not to the output file. Let's kill the
find
job, then restart it and send the output to
c.out
:
$ kill %2
[2] + Terminated find / name core print>c.out &
$ find / name core print >c.out &
[2] 1453
$ jobs
[2] ?Runningfind / name core print &
[1] Runningsleep 1000 &
We can work on something else until we get the completion message.
[2] +Done find / name core print>c.out &
Table 5.1. Job Control Commands
|
bg
|
put the current stopped job in the background
|
|
bg %
n
|
put the stopped job
n
in the background
|
|
fg
|
move the current background job into the foreground
|
|
fg %
n
|
move background job
n
into the foreground
|
|
jobs
|
display the status of all jobs
|
|
jobs -l
|
display the status of all jobs along with their process ids
|
|
jobs -p
|
display the process ids of all jobs
|
|
kill %
n
|
kill job
n
|
|
kill -l
|
list all valid signal
names
|
|
kill ?/span>
signal
%
n
|
send the specified signal to job
n
|
|
set -m
,
set -o monitor
|
enable job control; execute background jobs in a separate process
group
, and report the exit status of background jobs
|
|
stty tostop
|
prevent background jobs from generating output
|
|
stty -tostop
|
allow background jobs to generate output (default)
|
|
wait
|
wait for all background jobs to complete
|
|
wait %
n
|
wait for background job
n
to complete
|
|
Ctl-z
|
stop the current job
|
There are other ways to deal with job output. Jobs being executed in the background are prevented from generating output by setting
stty tostop
. Let's run the
find
job again with the
tostop
option enabled:
$ stty tostop
$ find / name core print &
[2] 1460
Now when the job has some output, we get this message:
[1] + Stopped(tty output) find / name core print &
The only way to see the
find
output is to bring the job back into the foreground.
$ fg
/usr/lbin/core
/home/anatole/bin/core
The
stty tostop
command can be put into your profile file so that background job output is by default disabled.
The
nohup
command can also be used to direct output from background jobs. It causes standard output
and
standard error to be automatically sent to
nohup.out
, or whatever file you give it. One added benefit: the
nohup
command will keep jobs running, even if you log out. Here we run the
find
job again using
nohup
. First we need to enable background job output:
$ stty tostop
$ nohup find / name core print &
[2] 1469
$ wait
Sending output to 'nohup.out'
[2] + Done nohup find / name core print &
The
find
job output is in
nohup.out
:
$ cat nohup.out
/usr/lbin/core
/home/anatole/bin/core
|