70 Shell stuff: job control and screen
Monday 26th March, 2007
Now there is also tmux.
Rob. April 2015.
A look at using shell job control, plus a quick overview of what I consider to be the best alternative to job control, GNU screen.
- run a task in the background
- bring a task to the foreground
- list jobs running in the background
- suspend a currently running task
- allow a suspended task to run in the background
- run a task in the background, and allow yourself to logout
- GNU screen
run a task in the background
This is something many people know. To run a task in the background, just type the command, followed by a space and an ampersand and hit "enter":
$ mutt &
This shows you that you have a job running in the background, and that it's process id is
(Note I wouldn't normally run mutt in the background; this is just an example.)
What this won't do is allow your task to continue running after you have logged out. In fact, if you try to log out (or exit your terminal), the shell will warn you that you have active tasks running:
exit There are stopped jobs. + Stopped mutt
We know the process id, so we could just kill the job. But that's a bit messy. :) It's always best to shut these things down properly.
So now we need to get back to our background job so we can shut it down.
bring a task to the foreground
Well, we know that this is job . So to switch to job , simply type:
Then shut the application down normally.
bash shell specific:
If you use the
bash shell (and possible some others), you can also use the more intuitive
$ fg 1
list jobs running in the background
If you don't know which job numbers were running in the background, you can use the command
jobs to find out, e.g:
+ Stopped mutt
jobs manpage will reveal more about the meanings behind the output from running the command.
suspend a currently running task
If you wish to suspend a task which is currently running in the foreground, type
<Ctrl>-z (hold down the Ctrl key and press "z" once). Note that this will suspend the task, not background it. To allow it to keep running in the background, you then need to type
bg <job id> and hit the return key:
$ tar cjvf /backup/rob/home.tar.bz2 .
./ ./bin/ ./bin/doom3 ...
<Ctrl>-z (suspend the job, the shell returns)
+ Stopped tar cjvf /backup/rob/home.tar.bz2 .
allow a suspended task to run in the background
$ bg 1 (allow job 1 to continue to run in the background)
+ tar cjvf /backup/rob/home.tar.bz2 . & $ ./bin/mutt.sh ./bin/url_handler.sh ./bin/bash_colours ...
Note that since I've opted for the verbose output from
tar, once the job is allowed to run it continues to output to stdout.
By default, the
bg command will background the last job you suspended, so in this example it's not strictly necessary to type the full
bg 1, but it's probably a good habit to get into.
run a task in the background, and allow yourself to logout
If you want to run a job in the background, and want it to continue to run after you have logged out (an impromptu manual backup which takes a long while to run, perhaps), then
nohup is one way of doing it.
nohup will run a command, allowing it to ignore hangup signals. It will not run in the background by default; that still requires you to put an ampersand at the end of the command.
$ nohup tar cjf /backup/rob/home.tar.bz2 . > /dev/null 2>&1 &
At first glance, this seems like a curious command. I've asked to run a tar backup of my home directory, ignoring hangup signals, in the background, but redirecting the output (stdout and stderr) to
/dev/null. Why redirect the output to
If stdout is a terminal, then by default
nohup redirects stdout and stderr to a file named
nohup.out (in the current directory). If that can't be created, then it redirects to
$HOME/nohup.out. If that can't be created, then the command is not run. So, unless you particularly need the data in
nohup.out cluttering up your filesystem, redirect it to
/dev/null, or at least to some other file with a name which makes more sense than
nohup.out. Some development hosts I've administered have literally been littered with
nohup.out files. Developers, eh?
One warning: if you run a command using
nohup and put it in the background, and you then close the terminal or logout, you will not be able to access that task directly using the
%25<N> commands. If you then want to stop the job before it has completed,
kill becomes your only option.
bash shell specific:
If you use the
bash shell, then you have an alternative (don't you always?) Instead of using
nohup, just run the command normally, put it in the background one of the two ways we've discussed, and then
disown -h the job.
$ tar cjf /backup/rob/home.tar.bz2 . &
$ disown -h
You can then safely logout or close your terminal. As with
nohup, if you close the terminal or logout, you will not be able to access that command directly using the
fg <N> commands.
screen is great. If you are working on a host which has
screen installed, then all that stuff about job control can be quietly ignored. Unfortunately, this is not always the case, especially with commercial Unices. In addition, you may have absent-mindedly kicked off a long-running job without having previously fired up
screen first, and then those job control commands may come in useful!
The main problem with
screen is that the initial learning curve is quite steep.
What I consider to be the main benefit of
screen is that your programs and sessions are preserved, even if your terminal, or X, or your remote connection crashes. You can also detach from a
screen session, and log out, leaving various programs running, and then login and re-attach to
screen later to see how they're getting on.
This is not the place to write a tutorial on how to use
screen; that's been done many times already (and I've listed a few of the tutorials at the end of this article), but here are a few of the more useful commands.
starts a new
|<Ctrl>-a "||list available windows|
|<Ctrl>-a c||create a new window and switch to it|
|<Ctrl>-a n||switch to the next window|
|<Ctrl>-a p||switch to the previous window|
|<Ctrl>-a A||rename the current window|
|<Ctrl>-a d||detach screen from the current terminal (programs will continue to run)|
|<Ctrl>-a ?||help; show key bindings|
|screen -ls||list running screen instances|
|screen -r <screen instance>||
attach to a specific
attach to the first detached
Note that all the <Ctrl>-a * commands are run from within
To completely shut down the
screen instance you're in, shut down all running programs and exit from the shells presented. When the final shell closes and you've been dropped back into your original terminal, you will have exited from (shut down)
GNU screen links
TIP Using screen - Gentoo Linux Wiki
As you might expect, the Gentoo dudes have got some excellent documentation on this subject.
GNU Screen - Jonathan McPherson
Another good resource. (This guy's vim documentation is very good too.)
A Guide to Efficiently Using Irssi and Screen :: f0rked.com
A nice little section on
screen, and you get to learn about irssi as well! Bargain!