9 killp - Send signal to processes (kill, terminate, ...) by PID until they end
11 killpgrp - Send signal to processes (kill, terminate, ...) by PGID until they end
13 killcmd - Send signal to processes (kill, terminate, ...) by command line until they end
15 killexe - Send signal to processes (kill, terminate, ...) by executable path until they end
19 killp [OPTIONS] <PID> [<PID> [...]]
23 Send signal to process(es) by PID, PGID (process group ID), command name, or by executable path
24 until the selected process(es) exists.
25 Ie. in usuall invocation, eg. C<killcmd java> tries to SIGTERM all java processes until at
26 least 1 exists, and returns only afterwards.
30 The following options control how B<killcmd> and B<killexe> finds processes.
31 Semantics are the same as in grep(1):
47 B<killcmd> looks for matching substring in the command's arguments too.
48 By default, only the command name is considered (first word in the command line).
52 B<killcmd> and B<killexe> look for matching substring in the command's full path too.
53 By default, only the basename is considered.
55 =item [--]signal=I<SIG>, [-]s=I<SIG>
58 See kill(1) and signal(7) for valid I<SIG> signal names and numbers.
60 =item [--]interval=I<IVAL>
62 How much to wait between attempts.
63 See sleep(1) for valid I<IVAL> intervals.
69 By default, prints what is being killed on the second attempt onward.
70 With --verbose, prints the first attempt too.
71 With --quiet, does not print what is being killed.
79 kill(1), pkill(1), pgrep(1), killall(1), signal(7)
90 .
/usr
/lib
/tool
/bash-utils
108 errx
-2 "Call by either of these names: killp, killpgrp, killcmd, killexe"
116 opt_match_command_args
=''
117 opt_match_full_path
=''
120 declare -A processes_left
121 declare -a grep_opts
=()
124 # explode "-abc" arguments into separate "-a -b -c" pieces.
130 while [ -n "${arg:$pos:1}" ]
132 args
+=("-${arg:$pos:1}")
142 for arg
in "${args[@]}"
145 signal
=*|sig
=*|s
=*|
--signal=*|
--sig=*|
-s=*)
148 interval
=*|
--interval=*)
155 -E|
--extended-regexp|
-F|
--fixed-strings|
-G|
--basic-regexp|
-P|
--perl-regexp|
-i|
--ignore-case|
-w|
--word-regexp|
-x|
--line-regexp)
159 if [ "$mode" != cmd
]
164 opt_match_command_args
=1
167 if [ "$mode" != cmd
-a "$mode" != exe
]
172 opt_match_full_path
=1
180 -n|
--dryrun|
--dry-run)
188 processes_left
[$arg]=''
196 # fill global $processes and $ps_title arrays
198 declare -g -a processes
202 proclist
=`ps -e o pid:1=,cmd= ww`
205 proclist
=`rcmod any=0 find /proc -mindepth 2 -maxdepth 2 -name exe -printf '%h %l\n' 2>/dev/null | cut -b7-`
209 proclist_to_search
=$proclist
211 if [ "$mode" = cmd
-a ! "$opt_match_command_args" ]
213 # discard the command arguments (keep the pid and the first word)
214 proclist_to_search
=`cut -f 1,2 -d ' ' <<< "$proclist_to_search"`
216 if [ \
( "$mode" = cmd
-o "$mode" = exe \
) -a ! "$opt_match_full_path" ]
218 # discard everything except pid (everything before space) and the basename (everything after the last slash)
219 proclist_to_search
=`sed -e 's, .*/\([^/]\+\)$, \1,' <<< "$proclist_to_search"`
225 processes
=("${!processes_left[@]}")
229 for cmd
in "${!processes_left[@]}"
231 grep_params
+=(-e "$cmd")
233 lines
=`echo "$proclist_to_search" | cut -d' ' -f2- | rcmod 1=0 grep --line-number "${grep_opts[@]}" "${grep_params[@]}" | cut -d: -f1`
235 declare -g -A ps_title
=()
236 while read -r pid title
238 if [ $pid = $$
-o $pid = "$PPID" ]; then continue; fi # except ourself and parent
239 ps_title
[$pid]=$title
240 done < <(echo "$proclist" | lines
$lines)
242 processes
=("${!ps_title[@]}")
249 # don't use bash built-in kill command
255 while [ ${#processes_left[@]} -gt 0 ]
257 if [ $attempt -gt 0 -a \
( $mode = cmd
-o $mode = exe \
) ]
259 # leave some time for the processes to exit.
260 # it's usually faster to wait here a bit,
261 # than rush to find processes, then wait a longer time if the processes
262 # were still there which we killed.
268 if [ ${#processes[@]} = 0 ]
270 # did not find any more of the named commands
273 warnx
"no such process found"
279 if [ $attempt -gt 0 ]
285 if [ ${#processes[@]} = 0 ]
287 # did not find more of the named commands
293 for proc
in "${processes[@]}"
310 if [ "$opt_verbose" -o $attempt -gt 0 ]
315 msg_end
=": ${ps_title[$proc]}"
318 warnx
"attempt $attempt: $id$msg_end"
324 kill -- -$Signal "$id" || true
329 warnx
"$what $proc terminated"
330 unset processes_left
[$proc]
333 warnx
"$what $proc terminated: ${ps_title[$proc]}"
340 attempt
=$
[attempt
+ 1]