Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to avoid kill -9 for the reasons described in the Useless Use of Kill -9 form letter. Is this function sufficient, or do I need to kill the kill processes after a timeout or take care of other subtleties?

soft_kill()
{
    # Try to avoid forcing a kill
    # @param $1: PID
    kill $1 || kill -INT $1 || kill -HUP $1 || \
    (echo "Could not kill $1" >&2; kill -KILL $1)
}

As an aside, what's a better name for this function? The current name reminds me of "Killing Me Softly", and manslaughter sounds a bit severe. Maybe spoon_kill (Google it)?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

Your soft_kill has a few issues.

  • killing a process isn't instantaneous but kill exits as soon as the signal is sent. You'll have to wait for a while before determining if the kill command succeed or if you need to escalate to -INT or -HUP.
  • kill returns(1) zero (success) if it's allowed to send the signal. Not if it succeeds to kill the process. So in your code only the first kill will be executed.

(1)

kill()
RETURN VALUES
If successful, kill() returns a value of zero. On failure, it returns a value of -1, does not send a signal, and sets errno to one of the following values:

EINVAL
The value of sig is an invalid or unsupported signal number.

EPERM
The user ID of the sending process is not privileged; its real or effective user ID does not match the real or saved user ID of the receiving process. Or, the process does not have permission to send the signal to any receiving process.

ESRCH
No process or process group can be found that corresponds to the one that pid specifies.

share|improve this answer
terminate () {
    # accepts PID as $1, defaults to current process
    local signals=(TERM INT QUIT HUP KILL) s=0 process=${1:-$$}
    local signal_qty=${#signals[@]}

    while pgrep $process >/dev/null
    do
        signal=${signals[s]}
        [[ $signal = KILL ]] && echo "Attempting to force kill it." >&2
        kill -$signal $process
        (( ++s >= signal_qty )) && { echo "It won't die." >&2; return 1; }
        sleep 1
    done
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.