UNIX-like operating systems (e.g., Linux, MacOS) have a handful of commands for managing your running programs (jobs) in the Terminal.
From your Terminal application, you have the ability to manually send jobs to run in the background, bring them to the foreground, or suspend them.
Below are the main job control commands with examples.
List the Current Jobs
If you have any jobs active in your session, you can view them via the
jobs command. If there are no active jobs, nothing will be output. Note that by “active” I am also referring to suspended jobs.
danielrobert in ~ $ jobs  + suspended vim .
Bringing Jobs to the Foreground
You can move the next job in the queue to the foreground via the
danielrobert in ~ $ fg
Additionally, if you multiple jobs running in the background, you can move a specific item to the foreground by it’s job id (
danielrobert in ~ $ jobs  - suspended vim .  + suspended (tty output) nano index.html danielrobert in ~ $ fg %2
In the above example, we have two jobs running.
fg will resume Vim, where
fg %2 will resume Nano.
Moving Jobs to the Background
There are a few different ways to send jobs to the background, whether that be in a running or suspended state.
In our examples above with the Vim and Nano sessions, we were working in those applications in the foreground and wanted to move them to the background (in a suspended state). This can be done with
control + z, while in the running application.
danielrobert in ~ $ sleep 60 ^Z  + 85158 suspended sleep 60
Alternatively, similar to moving jobs to the foreground with the
fg command, you can push the next job in the queue to the background via the
danielrobert in ~ $ bg
fg command, you can use the job id (
bg %[number]) to move a specific job to the background, if you have multiple jobs going. This is helpful if you have a suspended job that you want to continue to run in the background, freeing up the use of your current session.
danielrobert in ~ $ sleep 60 ^Z  + 85158 suspended sleep 60 danielrobert in ~ $ jobs  + suspended sleep 60 danielrobert in ~ $ bg %1  + 85158 continued sleep 60 danielrobert in ~ $ jobs  + running sleep 60
Lastly, if you want to start a job and immediately send it to run in the background, you can append an
& to the end of the command.
danielrobert in ~ $ sleep 60 &  86526 danielrobert in ~ $ jobs  + running sleep 60
Now that we’ve talked about some different options for managing jobs while they’re running, we’re going to want to know how to quit those jobs altogether. There are a couple of ways to do this.
One way to terminate a job that is running in the foreground is to use the
control + c command.
danielrobert in ~ $ caffeinate ^C
Another way to do this, regardless of the job status or whether it is running in the foreground / background, is to use the
kill command along with the job id.
danielrobert in ~ $ caffeinate &  87739 danielrobert in ~ $ jobs  + running caffeinate danielrobert in ~ $ kill %1  + 87739 terminated caffeinate danielrobert in ~ $ jobs danielrobert in ~ $
In addition, we can send a specific
kill signal along with our command and job id, formatted as
kill -[signal] %[number].
danielrobert in ~ $ kill -9 %1  + 87739 killed caffeinate
Some of the more commonly used signals are as follows:
1 HUP (hang up) 2 INT (interrupt) 3 QUIT (quit) 6 ABRT (abort) 9 KILL (non-catchable, non-ignorable kill) 14 ALRM (alarm clock) 15 TERM (software termination signal)
You can see a list of available signals on the
kill command via the
-l option flag.
danielrobert in ~ $ kill -l HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2
For a complete list of signals and their IDs, run
man signal in your Terminal application.