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
[1] + suspended vim .
Bringing Jobs to the Foreground
You can move the next job in the queue to the foreground via the fg
command.
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 (fg %[number]
).
danielrobert in ~ $ jobs
[1] - suspended vim .
[2] + 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
[1] + 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 bg
command.
danielrobert in ~ $ bg
Like the 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
[1] + 85158 suspended sleep 60
danielrobert in ~ $ jobs
[1] + suspended sleep 60
danielrobert in ~ $ bg %1
[1] + 85158 continued sleep 60
danielrobert in ~ $ jobs
[1] + 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 &
[1] 86526
danielrobert in ~ $ jobs
[1] + running sleep 60
Terminating Jobs
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 &
[1] 87739
danielrobert in ~ $ jobs
[1] + running caffeinate
danielrobert in ~ $ kill %1
[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
[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.