bin/murder @ d1b9a524e5fe default tip
More
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Wed, 22 Oct 2025 15:48:44 -0400 |
| parents | 758d680aa791 |
| children | (none) |
#!/bin/bash # https://gist.github.com/anonymous/32b1e619bc9e7fbe0eaa # Signal numbers to use. Configurable, as long as the number of elements in this # array matches the number of elements in $delays. signals=(15 2 1 9) # How much time processes should be given to finish their work before we try the # next signal. Configurable, as long as the number of elements in this array # matches the number of elements in $signals. delays=(10 10 15 1) # Takes a list of PIDs and ends the processes through increasingly rude means. function mykill { local ps='ps' ps="$ps o pid=" # Figure out the names of the signals we will try. local names=($(kill -l ${signals[@]})) local retval=0 if [[ $# -eq 0 ]]; then printf 'murder: Too few arguments: %d\nmurder: Usage: murder <PIDs...>\n' $# retval=1 else for pid in $@; do local index=0 # Try the next signal if the process is alive AND there are more # signals to attempt AND the previous kill reported no errors. while $ps $pid > /dev/null && [[ $index -lt ${#signals} ]] && [[ $retval -eq 0 ]]; do echo trying: kill -s ${signals[$index]} $pid output=$(kill -s ${signals[$index]} $pid 2>&1) retval=$? local killed=1 # Give the process some time to finish. sleep ${delays[$index]} index=$(($index + 1)) done if [[ -z $killed ]]; then printf 'murder: Process with PID %d does not exist.\n' $pid elif ! ${ps} ${pid} > /dev/null; then index=$(($index - 1)) printf 'murder: Killed process with PID %d with signal %s (%d).\n' $pid ${names[$index]} ${signals[$index]} elif [[ ${retval} -ne 0 ]]; then printf 'murder: kill failed: %s\n' $(echo ${output} | cut -d ' ' -f 5-) elif [[ ${index} -eq ${#signals} ]]; then printf 'murder: Failed to kill process with PID %d with signals %s\n' $pid "$(echo ${names[@]})" retval=-1 fi done fi return ${retval} } mykill $@