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.
If you have a process that you expect to take a long time, such as a long
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 &
This will start the copy operation as a child process of your
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
+ 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:
+ Done cp -r /mnt/bigdir /home &
If you want to return a job in the background to the foreground, you can type
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 %1
In this case, for shorthand, you can optionally omit
fg and it will work just
To temporarily suspend a process, you can press Ctrl+Z:
$ cp -r /mnt/bigdir /home
+ Stopped cp -r /mnt/bigdir /home
You can then continue it in the foreground or background with
fg %1 or
%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]
+ Stopped ssh crom
You can then resume it as you would any job by typing
tom@conan:~$ fg %1