Job control isn't always a good thing. For instance, I might want to start a long equipment-monitoring job running when I go home for the night. But if I simply put the job in the background and try to log out, zsh says zsh: you have running jobs. If I log out anyway, the shell sends my background job a HUP signal. I could use nohup (Section 23.10) to block the hangup signal, but there's a simpler way: tell the shell, "Don't use job control on this job." This is also true of jobs that I know are there -- a clock running on my X Window System display, for instance -- and that I'll never want to use job control on, so the jobs are just cluttering the jobs (Section 23.3) list.
To run a job without job control, the trick in most shells is to start the job in a subshell (Section 43.7), and put the job inside that subshell into the background. This is sometimes called "disowning" the job. Note that the ampersand (&) is inside the parentheses:
% (myprog -opts &)
The job won't appear in the jobs list, but ps (Section 24.5) should show it running. (You might need to use a "show all jobs" option like ps -x or ps -e.) If you use ps -l for a "long" listing, you'll see that the process' PPID (the process ID number of the parent process (Section 24.3)) is 1; this means that the process is now "owned" by init (Section 24.2). On the other hand, if you'd started the job in the background normally (without the subshell trick), you'd see that its PPID was that of the shell you started it from.
The Z shell has a more direct way: its &! and &| background operators. Both of them do the same thing: if you use one of those operators instead of plain &, the job will be disowned immediately; it won't appear in the jobs list.
In most shells, once you start a job without the subshell trick, the shell that started the job will continue to be its parent. (Some shells, like the C shells, will give up ownership of a child process and let it keep running when you end the shell -- that is, when you log out -- and then init will "inherit" the process.) In zsh and bash Version 2, though, you can change your mind after you start a job by using the shell's built-in disown command. Give disown the job number you want the shell to "forget." For instance, I'll start a background job and then disown it. It disappears from the job table, but giving ps its process ID shows that the job is still running:
zsh% myprog -opts& [1] 28954 zsh% jobs [1] + running myprog -opts zsh% disown %1 zsh% jobs zsh% ps 28954 PID TTY STAT TIME COMMAND 28954 pts/5 S 0:09 myprog -opts
If you don't give a job number, disown "forgets" the current job. The bash2 version of disown has options that zsh doesn't: disown -a disowns all jobs, and disown -r disowns only running jobs. The bash2 option -h does a different job: instead of removing a job from the job table, the job won't receive any HUP signal sent to the shell. This is similar to what the nohup command does.
-- JP
Copyright © 2003 O'Reilly & Associates. All rights reserved.