﻿<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://purl.org/atom/ns#">
	<link xmlns="http://purl.org/atom/ns#" type="text/html" rel="alternate" href="http://sial.org/blog/" title="Jeremy Mates’s Blog"/>
	<title xmlns="http://purl.org/atom/ns#">Jeremy Mates’s Blog</title>
	<entry xmlns="http://purl.org/atom/ns#" xmlns:default="http://www.w3.org/1999/xhtml">
		<title xmlns="http://purl.org/atom/ns#">KILL only if not already dead</title>
		<dc:subject>Books</dc:subject>
		<dc:subject>Coding</dc:subject>
		<summary xmlns="http://purl.org/atom/ns#">summary</summary>
		<content xmlns="http://purl.org/atom/ns#" mode="escaped">&lt;p&gt;Process restart scripts on Unix will normally send &lt;tt&gt;TERM&lt;/tt&gt; (-15) signal via &lt;a href="http://www.FreeBSD.org/cgi/man.cgi?query=kill&amp;sektion=1"&gt;&lt;tt&gt;kill(1)&lt;/tt&gt;&lt;/a&gt; or &lt;a href="http://www.FreeBSD.org/cgi/man.cgi?query=kill&amp;sektion=2"&gt;&lt;tt&gt;kill(2)&lt;/tt&gt;&lt;/a&gt; then move on, or send a brutal &lt;tt&gt;KILL&lt;/tt&gt; (-9). Neither approach should be used: a &lt;tt&gt;TERM&lt;/tt&gt; signal may leave a process running, and a &lt;tt&gt;KILL&lt;/tt&gt; must only be sent as a last resort. &lt;tt&gt;KILL&lt;/tt&gt; prevents cleanup of shared memory, temporary files, and other open resources. Instead, send a &lt;tt&gt;TERM&lt;/tt&gt; signal, then check whether the process has exited properly. If not, only then use the &lt;tt&gt;KILL&lt;/tt&gt; signal.&lt;/p&gt;
&lt;p&gt;The following script will help test processing killing code. The script ignores the default &lt;tt&gt;TERM&lt;/tt&gt; signal, requiring some other signal to stop the process, such as &lt;tt&gt;INT&lt;/tt&gt; (-2, or &lt;kbd&gt;ctrl+c&lt;/kbd&gt;) or &lt;tt&gt;KILL&lt;/tt&gt;. The &lt;a href="http://perldoc.perl.org/perlipc.html"&gt;&lt;tt&gt;perlipc&lt;/tt&gt; documentation contains more information on signal handling&lt;/a&gt; in Perl.&lt;/p&gt;
&lt;p class="sial-block-code"&gt;#!/usr/bin/perl -l
print $$;
$SIG{TERM} = 'IGNORE';
$SIG{INT}  = sub { print "whoa"; exit };
sleep 3 while 1;&lt;/p&gt;
&lt;p&gt;GNU &lt;tt&gt;ps&lt;/tt&gt; contains options to match running processes, such as:&lt;/p&gt;
&lt;p class="sial-block-code"&gt;pid_check=`ps ho pid $pid`
if [ -z "$pid_check" ]; then
  echo "info: process not running: pid=$pid"
fi&lt;/p&gt;
&lt;p&gt;However, these options do not work on other &lt;a href="http://www.FreeBSD.org/cgi/man.cgi?query=ps&amp;sektion=1"&gt;&lt;tt&gt;ps(1)&lt;/tt&gt;&lt;/a&gt; implementations. Inspecting the result of &lt;tt&gt;kill -0 $pid&lt;/tt&gt; should be more portable, though must be tested on each new flavor of Unix. Example shell code to kill a process and ensure it exits:&lt;/p&gt;
&lt;p class="sial-block-code"&gt;#!/bin/sh

# Returns 0 if supplied pid not found,
# 1 if still running. Back-off delay
# allows slow processes to spin down.
confirm_process_exit () {
  PID=$1

  for delay in 0 1 2 3 5 8; do
    echo -n .
    sleep $delay

    if ! kill -0 $PID &gt;/dev/null; then
      return 0
    fi
  done

  return 1
}

# Kill process, then ensure exits
kill $1
confirm_process_exit $1
STATUS=$?

if [ $STATUS -eq 1 ]; then
  kill -9 $1
fi&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://www.amazon.com/o/ASIN/0134514947/sialorg-20/ref=nosim"&gt;Portable Shell Programming&lt;/a&gt; book covers &lt;a href="http://www.FreeBSD.org/cgi/man.cgi?query=ps&amp;sektion=1"&gt;&lt;tt&gt;ps(1)&lt;/tt&gt;&lt;/a&gt; and other shell portability concerns. If possible, use Perl or another modern language, as the loop handling code around &lt;a href="http://www.FreeBSD.org/cgi/man.cgi?query=kill&amp;sektion=2"&gt;&lt;tt&gt;kill(2)&lt;/tt&gt;&lt;/a&gt; will be more testable and portable than the equivalent shell code.&lt;/p&gt;
&lt;p&gt;Slow to exit applications will also require special handling, as they may take upwards of a minute to spin down. Java embedded with Oracle… uggh.&lt;/p&gt;
&lt;p&gt;On a somewhat related note, ensure new application code load tested before seeing production use. Systems often exhibit unexpected behavior under heavy CPU or memory load.&lt;/p&gt;




&lt;!-- technorati tags start --&gt;&lt;p style="text-align:right;font-size:10px;"&gt;Technorati Tags: &lt;a href="http://www.technorati.com/tag/coding" rel="tag"&gt;coding&lt;/a&gt;, &lt;a href="http://www.technorati.com/tag/Unix" rel="tag"&gt;Unix&lt;/a&gt;&lt;/p&gt;&lt;!-- technorati tags end --&gt;
&lt;br /&gt;

		</content>
		<issued xmlns="http://purl.org/atom/ns#">2006-10-06T23:26:19-0700</issued>
		<link xmlns="http://purl.org/atom/ns#" type="text/html" rel="alternate" href="http://sial.org/blog/2006/10/kill_only_if_not_already_dead.html" title=""/>
		<id xmlns="http://purl.org/atom/ns#">81</id>
	</entry>
</feed>
