17.9. Process Control
When you run a program or command at the shell prompt, the shell
usually creates a new process that will run the program or command
(a process is the operating systems abstraction of a running program).
There are a few built-in shell commands that the shell process executes
itself (e.g., cd
), but most are run as separate processes.
See Chapter 13: The Operating System
for more information about processes.
The unix shell supports process control features, which are ways to specify how a program is run by the shell, and ways to interact with the process as it runs.
17.9.1. Running in the foreground and background
When a program is run at the shell prompt, it runs in the foreground by
default, meaning that the program runs to completion before the shell program
runs again and prints out the next prompt. However, programs can also be run
in the background, meaning that the shell starts the program running but does
not wait until it completes before printing out the next prompt; this allows a
user to enter another command while the program is still running. To tell the
shell to run a program in the background, the user adds an &
at the end of
the command line. For example, here is how to tell the shell to run an a.out
program in the background:
$ ./a.out & $
The ps
command can be used to list all the programs running in the shell.
For example, here we start two a.out
programs running in the background,
and then type ps
:
$ ./a.out & $ ./a.out & $ ps PID TTY TIME CMD 2729 pts/72 0:03.91 bash 3582 pts/72 0:00.00 ./a.out 3583 pts/72 0:00.00 ./a.out 3584 pts/72 0:00.00 ps
In the example output, you can see two a.out
processes are running
in addition to the Bash shell process and the ps
process. With each
process is listed its process id
, a unique identifier the the
operating system keeps for each process (i.e., the bash
process id
is 2729
and the two processes running the a.out
program have
process ids 3582
and 3583
).
A process running in the background can be moved to the foreground using
the fg
command:
$ ./a.out & # run a.out in the background $ ps PID TTY TIME CMD 2729 pts/72 0:03.91 bash 3584 pts/72 0:00.00 ./a.out $ fg # move a.out to the foreground (the shell waits for it to exit) $ ps # run ps at the shell prompt (a.out has exited) PID TTY TIME CMD 2729 pts/72 0:03.91 bash
By typing CTRL-Z
a process running in the foreground can be
interrupted and suspended meaning that its execution is paused
(it is not running). This causes the shell to run again and print out
a shell prompt. If the user types bg
, the suspended process will continue
running, but now run in the background. If the user types fg
the
suspended process will continue running in the foreground again.
Here are some examples:
$ ./a.out # run a.out in the foreground # type CTRL-Z to suspend a.out [1] Stopped ./a.out $ ps PID TTY TIME CMD 2729 pts/72 0:03.91 bash 3588 pts/72 0:00.00 ./a.out $ bg # unsuspend a.out and run in background $ ps PID TTY TIME CMD 2729 pts/72 0:03.91 bash 3588 pts/72 0:00.00 ./a.out $ fg # run backgrounded process in the foreground
17.9.2. Killing a running processes
The kill
and pkill
commands are used to send a signal from the shell
process to another processes. Signals are a way in which one process can
notify another process to do something. Every signal triggers a default
behavior, exiting or ignoring are two common default options (see
Chapter 13: The Operating System for
more information about signals).
The kill
command takes the process id (PID) of
the process to send the signal, and the pkill
command takes the name of the
command or executable file to which to send the signal (pkill
sends the
signal to all running processes with the specified name that are owned by the
user running pkill
). Both kill
and pkill
take an optional command line
argument that species the specific signal to send to the process. Without
specifying the specific signal, both default to sending a termination signal
(SIGTERM
) to the specified process(s).
A common use of these commands is to send a process a signal
to tell it to exit (this is where kill
gets its unfortunate name).
Note that a process running in the foreground also can be killed by
typing CTRL-C
, which sends the process running in the foreground
a SIGINT
signal that by default tells the process to exit.
Here is an example call to pkill
to kill all a.out
processes:
$ ps PID TTY TIME CMD 3032597 pts/72 00:00:00 bash 3033074 pts/72 00:00:04 a.out 3033076 pts/72 00:00:03 a.out 3033089 pts/72 00:00:02 a.out 3033105 pts/72 00:00:00 ps $ pkill a.out [1] Terminated ./a.out [2]- Terminated ./a.out [3]+ Terminated ./a.out $ ps PID TTY TIME CMD 3032597 pts/72 00:00:00 bash 3033128 pts/72 00:00:00 ps
Here is an example call to kill
to kill a specific a.out
processes
given its PID (the second process in the first ps
listing):
$ ps PID TTY TIME CMD 3032597 pts/72 00:00:00 bash 3033870 pts/72 00:00:03 a.out 3033883 pts/72 00:00:02 a.out 3033886 pts/72 00:00:01 a.out 3033897 pts/72 00:00:00 ps $ kill 3033883 [2]- Terminated ./a.out $ ps PID TTY TIME CMD 3032597 pts/72 00:00:00 bash 3033870 pts/72 00:00:18 a.out 3033886 pts/72 00:00:16 a.out 3033974 pts/72 00:00:00 ps
Note that kill
only killed the specific process with a matching pid value
and not every process running the same program (a.out
).
In both of these examples, we are not specifying the signal to send. Without
any optional command line options, kill
and pkill
send the process
the terminate signal (SIGTERM
or signal number 15
).
By default, SIGTERM
tells the signaled process to exit. Sometimes you
will see calls to kill
and pkill
that include a different signal number.
In this case the signal number is specified as a command line argument
(-<signal number>'). For example, we could have included the signal
number `-9
to send them the SIGKILL
signal (yet another way to tell
a process to exit):
$ pkill -9 a.out $ kill -9 3033883
In general, these commands can be used to send any signal to a process. For
example, to send a process a SIGALRM
signal (which is signal number 14
),
you could do this:
$ kill -14 3033883
If the process doesn’t have a signal handler for the SIGALRM
signal, the
default behavior is that the SIGALRM
signal is just ignored.
The man page for signal
lists the minimal set of signals (and their
signal numbers) that are defined in the system: man 7 signal
.
17.9.3. References
For more information see:
-
The man pages for these commands (e.g.,
man ps
,man pkill
,man 7 signal
) -
most used Unix commands from cheat-sheets.org
-
Bash Reference Manual from gnu.org.