killでプロセスIDかプロセス名を補完する
[zsh] killコマンドでpidやコマンド名の補完 〜Just another Ruby porter,
に触発されてbashで同じようなことをしてみる。
$ kill 224<TAB> 22421 hirose31 pts/15 00:00:06 emacs 22491 hirose31 tty1 00:00:01 kterm 22493 hirose31 pts/16 00:00:00 /bin/bash $ kill su<TAB> su - 21928 root pts/14 00:00:00 sudo xconsole -fg red -bg g 21653 root tty1 00:00:00 supervise log 2267 root ? 00:00:00 supervise log 2269 root ? 00:00:00 supervise qmail-send 2268 root ? 00:00:00 supervise smtpd 2266 root ? 00:00:00
コードはこんな感じ。元はbash-completionからパクりました。
## kill _signals() { local i # standard signal completion is rather braindead, so we need # to hack around to get what we want here, which is to # complete on a dash, followed by the signal name minus # the SIG prefix COMPREPLY=( $( compgen -A signal SIG${cur#-} )) for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do COMPREPLY[i]=-${COMPREPLY[i]#SIG} done } _pids() { case $cur in [a-zA-Z]*) c=$( compgen -W '$( ps axo cmd | sed 1d )' -- $cur | wc -l) if [ $c -eq 1 ]; then # compgenを使ってないので不安… COMPREPLY=( $(ps axo pid,cmd | awk "\$2 ~ /^${cur}/{print \$1}") ) else IFS=' ' COMPREPLY=( $( compgen -W '$( ps axo cmd,pid,user,tty,time | sed 1d | cut -c 1-76 )' -- $cur) ) fi ;; *) c=$( compgen -W '$( ps axo pid | sed 1d )' -- $cur | wc -l) if [ $c -eq 1 ]; then COMPREPLY=( $( compgen -W '$( ps axo pid | sed 1d )' -- $cur) ) else IFS=' ' COMPREPLY=( $( compgen -W '$( ps axo pid,user,tty,time,cmd | sed 1d | cut -c 1-76 )' -- $cur) ) fi ;; esac } _kill() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} if [ $COMP_CWORD -eq 1 ] && [[ "$cur" == -* ]]; then # return list of available signals _signals else # return list of available PIDs _pids fi } complete -F _kill kill