Oftentimes you may wish to start a process on the Bash shell without having to wait for it to actually complete, but still be notified when it does. Similarly, it may be helpful to temporarily stop a task while it’s running without actually quitting it, so that you can do other things with the terminal. For these kinds of tasks, Bash’s built-in job control is very useful.
Backgrounding processes
If you have a process that you expect to take a long time, such as a long cp
or scp
operation, you can start it in the background of your current shell by
adding an ampersand to it as a suffix:
$ cp -r /mnt/bigdir /home &
[1] 2305
This will start the copy operation as a child process of your bash
instance,
but will return you to the prompt to enter any other commands you might want to
run while that’s going.
The output from this command shown above gives both the job number of 1, and
the process ID of the new task, 2305. You can view the list of jobs for the
current shell with the builtin jobs
:
$ jobs
[1]+ Running cp -r /mnt/bigdir /home &
If the job finishes or otherwise terminates while it’s backgrounded, you should see a message in the terminal the next time you update it with a newline:
[1]+ Done cp -r /mnt/bigdir /home &
Foregrounding processes
If you want to return a job in the background to the foreground, you can type
fg
:
$ fg
cp -r /mnt/bigdir /home &
If you have more than one job backgrounded, you should specify the particular
job to bring to the foreground with a parameter to fg
:
$ fg %1
In this case, for shorthand, you can optionally omit fg
and it will work just
the same:
$ %1
Suspending processes
To temporarily suspend a process, you can press Ctrl+Z:
$ cp -r /mnt/bigdir /home
^Z
[1]+ Stopped cp -r /mnt/bigdir /home
You can then continue it in the foreground or background with fg %1
or bg
%1
respectively, as above.
This is particularly useful while in a text editor; instead of quitting the
editor to get back to a shell, or dropping into a subshell from it, you can
suspend it temporarily and return to it with fg
once you’re ready.
Dealing with output
While a job is running in the background, it may still print its standard
output and standard error streams to your terminal. You can head this off by
redirecting both streams to /dev/null
for verbose commands:
$ cp -rv /mnt/bigdir /home &>/dev/null
However, if the output of the task is actually of interest to you, this may be a case where you should fire up another terminal emulator, perhaps in GNU Screen or tmux, rather than using simple job control.
Suspending SSH sessions
As a special case, you can suspend an SSH session using an SSH escape sequence. Type a newline followed by a ~ character, and finally press Ctrl+Z to background your SSH session and return to the terminal from which you invoked it.
tom@conan:~$ ssh crom
tom@crom:~$ ~^Z [suspend ssh]
[1]+ Stopped ssh crom
tom@conan:~$
You can then resume it as you would any job by typing fg
:
tom@conan:~$ fg %1
ssh crom
tom@crom:~$