Bash Job Control
You may think you can do only one thing at a time in Bash. This notion seems plausible – you have exactly one command prompt, so how should you run different commands at the same time? However, this notion is wrong. Bash offers a set of built-in multitasking features called Job Control.
Why you want to use it
Suppose you are working in Vim when suddenly you need to look up something in a man page. What do you do?
You could save the file you are working on, close Vim, check the man page, open the file in Vim again, navigate back to the line you edited last, and finally continue your work (now having already forgotten what you read in the man page) … Alternatively, in a graphical desktop environment, you could open another terminal window and check the man page there, but this is an equally awkward interruption of your workflow. Or if you spend much time on the command line you are possibly in a tmux session already so you could simply split your terminal window to open the man page. (The last option is actually a real alternative to using Job Control since tmux offers a boatload of other useful features. However, in some situations it is just plain overkill to use tmux.)
Leveraging Job Control you would do this: Press Ctrl-Z
to suspend Vim, check the man page, and type fg
to get back
to your Vim session which is waiting for you in exactly the state you
left it. Try it now!
How it works
The commands available for Job Control are Ctrl-Z
,
jobs
, fg
, bg
and the
&
operator.
Ctrl-Z
suspends the currently running process (be it an
interactive program like Vim or htop or a long running command like a
wget download) and gives you a new command prompt. To get back to the
suspended process and continue it in the foreground type
fg
.
A suspended process will be interrupted and by default won’t continue
running in the background. This is okay for interactive programs but
less so for long running commands that should silently continue their
work in the background without cluttering up your shell prompt. Here the
bg
command is what you want: While fg
continues a suspended job in the foreground (i.e., it puts it
back at your shell prompt) bg
makes a suspended job
continue running invisibly in the background.
If you know up front that a command you are about to issue will run
for a long time you can take a shortcut to schedule it for background
execution; instead of suspending the command with Ctrl-Z
and sending it to the background with bg
you can just
append the &
operator to the command which sends it
directly to the background:
$ wget http://example.org/some-large-file &
When you are juggling with several jobs use the jobs
command to get a list of all running and suspended commands:
$ jobs
[1]+ Stopped vim foo
[2] Stopped man bash
[3]- Running wget http://example.org/some-large-file &
By default, the fg
and bg
commands continue
the last suspended job (which is marked by the + sign in the output
above). To specify another job from the list returned by the
jobs
command give its job number or (if this is
unambiguous) the job’s command name to the fg
or
bg
command. The following three commands are all equivalent
given the job list above:
$ fg
$ fg 1
$ fg vim