Project 40. Manage Processes"How do I abort an errant process?" This project shows you how to send a signal to a process to ask it to finish, tell it to finish, or ask it to restart. It uses the ps command, covered in Project 39, to find a process and the kill command to send the appropriate signal. The project also covers techniques for changing process priority by using renice and nice. Tip
Understand SignalsSignals are a feature built into Unix. A signal is like an interrupt: Sending a signal to a process causes the process to stop what it's doing and to respond to the signal. Signals give us a way of tapping a process on the shoulder and asking it to take specific action, such as restarting, terminating, or temporarily halting. The most useful signals are
There are many more signals, and individual processes can elect to respond to some signals and ignore others. Each process may respond to a signal in its own particular way. Stop Interactive ProcessesInteractive processes (those that run in Terminal and read from the keyboard) usually respond to the signals INT and QUIT by terminating and to the signal SUSP by suspending and becoming a background job. For convenience, these signals are mapped to the following key sequences. Learn More
To have bash list current key mappings, type $ stty -e Learn More
You may change the key mappingsfor example, setting INT to Control-x by typing $ stty intr ^x (Type the caret [^] symbol followed by x.) See the stty man page for more information. Tip
Kill Errant ProcessesSuppose that we wish to abort a process. It might be a Unix daemon, a Bash script, or an application like Calculator. To do so, we send a TERM signal from kill. The kill command identifies a process by its process identification number (PID), whereas we humans usually refer to a process by its name. We'll use the ps grep combination, covered in Project 39, to translate from process name to PID. $ ps -xc | grep "Calculator" 24815 ?? S 0:00.63 Calculator The PID is shown as the first item on the linein this case, 24815. To terminate Calculator, we need only issue the command $ kill 24815 and it silently dies. Unless instructed otherwise, kill sends a TERM signal. Tip
Force QuitSuppose that Calculator has crashed and is not responding to the TERM signal. This situation calls for a KILL (force-quit) signal. To send a specific signal from kill, apply option s, followed by the name of the desired signal. $ kill -s KILL 24815 Learn More
Define a Killer FunctionWe can easily write a Bash function to kill a process by name. Here's the definition for a function called killx. killx () { kill $(ps -xc | grep -w $* | awk '{print $1}');} We'd use it to terminate a processCalculator, for exampleby typing $ killx Calculator Learn More
Let's build killx stage by stage to see how it works. First, to isolate the PID of the target process, we employ the usual ps-to-grep trick. $ ps -xc | grep -w Calculator Adding a third stage to the command, we pipe the grep output to awk and tell it to display only the PID (field 1 of each line). $ ps -xc | grep -w Calculator | awk '{print $1}' $ 24815 Learn More
Now let's kill (abort) the process by using kill. We'll enclose the pipeline we just built inside $(), which tells bash to execute it; write the result back to the command line; and then execute the remainder of the command line. (Other shells, such as tcsh, use the syntax `command` instead of $(command).) Before we do any actual killing, use echo to demonstrate that the expression enclosed by $() still outputs the PID. $ echo $(ps -xc | grep -w Calculator | awk '{print $1}') 24815 All that remains now is to pass the PID to kill instead of echoing it. $ kill $(ps -xc | grep -w Calculator | awk '{print $1}') To make a function of this command, we enclose it in braces and assign it to killx (). Obviously, we don't want to kill Calculator every timewe want to pass an argument to killxso we'll replace Calculator with the marker $*. When the function is executed, the argument passed to killx replaces $*. $ killx() { kill $(ps -xc | grep -w $* | awk '{print $1}');} Tip
RestartMany system services, like the Apache Web server, are daemonsprocesses that sit in the background until they are needed. If you ever have to restart such a process (after changing a configuration file, for example), check its man page to see whether it understands the HUP signal. Many daemons do, and they interpret it as a request to reload their configuration settings. We tell process 12345 to reload its configuration by typing $ sudo kill -HUP 12345 Restarting a daemon is more elegant than terminating and restarting it. Change Process PriorityUnix dynamically assigns a priority to each process, based on how much processor time the process has been using. A process that has had little CPU time is given a higher priority and moved toward the front of the CPU queue. A process that has hogged the CPU is given a lower priority and moved backward in the queue. When the CPU is busy, higher-priority processes are favored. Make a Process Play NiceSuppose that a background process is hogging a lot of CPU time, slowing your word processor. You can use the command renice to reduce the background process's priority so that it'll be treated less favorably. In the following example, iPhoto is rearranging its library, slowing the applications I'm working on. I'm going to make it nicerless likely to hog the CPU by giving it a nice value of 15. Values can range from 0 (the default) to 20 (the nicest and least likely to hog the CPU). Note
First, run ps with option -O (letter oh) to tell ps to report the priority of a process (pri) and its nice value (nice). $ ps -xc -O pri,nice | grep iPhoto PID PRI NI TT STAT TIME COMMAND 25132 38 0 ?? R 0:02.70 iPhoto Next, make iPhoto nicer by typing the renice command, followed by the new nice value and the target PID. $ renice 15 25132 Examine the status of iPhoto again, and we see that it reflects the new nice value of 15. $ ps -xc -O pri,nice | grep iPhoto PID PRI NI TT STAT TIME COMMAND 25132 30 15 ?? SN 0:04.71 iPhoto It's possible to influence a process's priority in the other direction, giving it more CPU time, by specifying a nice value between 0 (the default) and -20 (the nastiest and most likely to hog the CPU). Because this sort of thing can mess up the system, only the root user is allowed to be nasty. $ sudo renice -15 25132 Password: $ ps -xc -O pri,nice | grep iPhoto PID PRI NI TT STAT TIME COMMAND 25132 18 -15 ?? S< 0:04.72 iPhoto Launch a nice ProcessYou can alter commands' nice values as you launch them by invoking them through the command nice. To launch command number-cruncher, assign it a low priority, and send it to the background, type $ nice -n 20 ./number-cruncher & The allowable range of nice values is the same as those for renice, with negative values increasing priority and positive values decreasing it. Also, as with renice, only the root user may launch a process with increased priority (a negative nice value). |