Unix: Job control
Processes
Manipulating Unix processes used to be an important aspect of mastering Unix back in the old days when a Unix “terminal” actually was a physical CRT terminal – and you only had one. If your terminal was attached to a busy process, and you needed to run a second process, you would have to borrow asecond CRT terminal from a collegue. Or, instead of borrowing a terminal, you could detach a process from your terminal by putting it in the background, thereby making the terminal available again.
These days, Unix “terminals” tend to be windows on a bitmapped screen, and you can have so many as you want. Hence, most of the reasons for having a need to manipulate processes has vanished. But process manipulation is still part of Unix. If you want to learn it, here are the basics.
Information about processes
A process is an executing program identified by a unique PID (process identifier). To see information about your processes, with their associated PID and status, type:
$ ps
A process may be in the foreground, in the background, or be suspended. In general the shell does not return the Unix prompt until the current process has finished executing.
Some processes take a long time to run and make the terminal unavailable to the user. Backgrounding a long process has the effect that the Unix prompt is returned immediately, and other tasks can be carried out while the original process continues executing.
Backgrounding a process
To background a process, type an &
at the end of the command line.
To demonstrate, I shall use the command sleep
.
This is a standard command that just sleeps (waits) a given number of
seconds before completing. The command sleep 10
will
sleep for 10 seconds before terminating. Until the command has
terminated, your terminal will be uanavailable, and you will not be
able to type in another command.
To run sleep in the background, instead of typing:
$ sleep 10
you type:
$ sleep 10 & [1] 18156 $
The &
at the end of the command line tells the
shell to run the job in the background (i.e. detached from the
termibal) and to give you back the command line prompt straight
away. This allows you do run other programs in the same terminal while
waiting for that one to finish.
The first line in the above example is typed in by the user. The next line, indicating job number and PID, is returned by the machine. The third line shows that the command line prompt is available again instantly, before the sleep command has terminated.
The second line shows how the shell reports that a job is put in the background. The job number (numbered from 1) is enclosed in square brackets. The PID (18156 in the example above) is a system-wide unique identifier.
Backgrounding, usually together with redirection of output, is sometimes useful for jobs which will take a long time to complete.
Listing background and stopped processes
When a process started from the current shell is backgrounded or
stopped, it will be entered onto a list along with a job number. To
examine this list, use the jobs
command.
An example of a list of job could be:
$ jobs [1] Running sleep 600 [3]- Stopped ls -R | more [4]+ Stopped vim
The number in square brackets is the job's jobnumber.
The +
sign indicates that this job was stopped last.
This is also known as the current job.
The -
sign indicates that this job was the
second to last job to be stopped.
To put in the foreground the current job, just type:
$ fg
Given the list of jobs in the example above, this will restart job number 4 (vim).
To put in the foreground a specific process in the job queue, include the jobnumber in the command.
For example, given the list of jobs in the example above, to restart sleep 600
, type:
$ fg %1
Notice that there should be a percentage sign in front of the jobnumber.
Backgrounding a current foreground process
You can also place a process currently running in the foreground in the background.
To try this out, at the comamnd line prompt, type:
$ sleep 600
This starts a process that will just sleep for 600 seconds (10 minutes) and places it in the foreground.
To regain the terminal before the 10 minutes are up you can
suspend (stop) the process running in the foreground by typing
[Ctrl]-Z
. If we examine the jobs queue afterwars
we will see something similar to this.
$ jobs [3]- Stopped ls -R | more [4] Stopped vim [5]+ Stopped sleep 600
However, we the job to continue running, but in the background.
Since it is the current process, as indicated by the +
,
the following command will do that:
$ bg
Re-examining the jobs queue, we see that it is now running:
$ jobs [3]+ Stopped ls -R | more [4] Stopped vim [5]- Running sleep 600
If we try the same trick with job 4 (vim), it won't work. It becomes running, but is immediately stopped again. This is because vim (an interactive text editor) is unable to run unless it is attached to the terminal. Non-interactive programs such as sleep is fine running in the background, but interactive programs such as vim must be in the foreground to run.
Terminate (kill) a process
It is sometimes necessary to kill a process (for example, when an executing program becomes totally unresponsive due to some error).
To kill a job running in the foreground, type [Ctrl-]-C
). For example;
$ sleep 600 [Ctrl]-C $
To kill a suspended or background process, type kill %jobnumber
. For example:
$ sleep 600 & $ jobs [3]+ Stopped ls -R | more [4] Stopped vim [5]- Running sleep 600 $ kill %5 [5]- Terminated sleep 600 $ jobs [3]+ Stopped ls -R | more [4]- Stopped vim
In this example, the job with jobnumber 5 was killed.
Instead of using the job number to identify the process to kill, you can use its PID.
You can use the command ps
to find PIDs. Example:.
$ ps PID TTY TIME CMD 4218 pts/1 00:00:00 bash 9816 pts/1 00:00:22 vim 12867 pts/1 00:00:00 sleep 12879 pts/1 00:00:00 ps $ kill 12867 $ [5]- Terminated sleep 600
When using the kill command, a signal is sent to the process. The default signal only request that the process terminates. The process is expected to clean up by flushing buffers, closing open files, etc., and then terminate. However, the process is free to ignore it.
If a process ignores the default signal, it can still be killed with the following command:
$ kill -9 PID
This sends signal 9
to the process identified by PID.
Signal 9
can't be handled or ignored. This is pretty brutal, since
the process can't handle the signal, it can't clean up before terminating.
It is not possible (unless you're root) to kill off other users' processes.
Summary
Command | Meaning |
---|---|
command & |
run command in background |
[Ctrl]-Z |
suspend the job running in the foreground |
[Ctrl]-C |
kill the job running in the foreground |
jobs |
list current jobs |
ps |
list current processes |
bg %jobnumber |
place jobnumber in the background |
fg %jobnumber |
place jobnumber in the foreground |
kill %jobnumber |
kill (signal) process with jobnumber |
kill number |
kill process number |