Background, running jobs in
Contents |
Overview
There are three basic methods to run jobs in the background: by ampersand, by cron, and by at.
Ampersand
This is the simplest method: when executing a command from the shell, simply append an ampersand to it, and the shell will execute it in the background and return you a process id number:
ph34r# /usr/bin/perl /home/jimbo/dostuff.pl & [1] 84190 ph34r# ps waux | grep 84190 root 84190 0.0 0.1 1460 788 ?? Is 4:02PM 0:02.19 /usr/bin/perl /home/jimbo/dostuff.pl
However, if you should exit the shell, the background process will also be killed:
ph34r# exit % ps waux | grep 84190 %
Our job got killed when we exited the shell because it was a child process of the shell. If we wanted to be able to close the shell and still keep the job running, we should have used at.
Another interesting use of the ampersand character from the shell is to cause one task to run after another task finishes:
ph34r# echo this && echo is && echo just && echo an && echo example this is just an example ph34r#
You can also append a single ampersand at the end of a bunch of double-ampersand linked commands in order to cause the whole kit and kaboodle to run in the background, while still making each individual command wait on the last one to finish before it starts.
cron
cron is the system's automated scheduling utility for repeated tasks. Its usage is complex enough that it's better for you to visit the cron article itself if you want to learn how to use it; but in a nutshell special files called crontabs are used to tell cron what tasks you want it to perform, under which user contexts, and when. cron jobs are not bound to any particular shell, and will fire off on schedule without any user intervention and regardless of whether any particular user - or anyone at all - is interactively logged into the system.
at
at is the system's scheduling utility for single-execution jobs: when you want something to happen at some particular point in time, but only once, you schedule it with at. Once every five minutes, cron fires up atrun, which checks the at queue and pops jobs that are due to process off the queue and runs them.
at jobs are not children of any shell process, and just like cron jobs, will run regardless of whether any particular user or even any user at all is logged into the system interactively. This makes at a handy way to cause a long-running job to start up immediately, while allowing you to close your shell and go elsewhere (or to make sure a REALLY long-running job will continue running even if your shell closes for some reason out of your control, such as an internet outage).
When using at to schedule a job to run immediately, however, you may get annoyed by having to wait for the next 5-minute mark for the job to run: if so, you can always fire up atrun yourself, rather than waiting for cron to do it for you. This won't hurt anything, and it will go ahead and pop jobs that are due to run out of the queue immediately so you don't have to sit around and wait.
ph34r# date Fri Feb 29 15:50:29 EST 2008 ph34r# at now /bin/sh /home/jimbo/some_long_job.sh ^D (user pressed ctrl-D) Job 9 will be executed using /bin/sh ph34r# atq Date Owner Queue Job# Fri Feb 29 15:50:48 EST 2008 root c 9 ph34r# /usr/libexec/atrun ph34r# atq ph34r# exit % ps waux | grep some_long_job root 20472 0.0 0.1 1460 788 ?? Ss 12:02PM 0:02.19 /bin/sh /home/jimbo/some_long_job.sh %
As you can see, we scheduled the job for immediate execution, saw that it was pushed into the queue, manually fired off atrun, then checked to see that it had popped from the queue. Seeing that it had popped from the queue, we exited our shell (note the transition from the "ph34r# " prompt to the "% " prompt) and checked to see that the job was still running - and sure enough, it was. Miller time!