プロセスをあいまい検索してkillするツールをGoで作った

初めに

仕事しているとプロセスをkillすることがたまにあると思います。

だいたいはpsawkgrepで必要なプロセスIDを抽出してkillコマンドに渡していますが、 ぼくはそれがとても面倒に感じているので、あいまい検索してプロセスをkillしたいなと思ってfk(fuzzy-finder-killer)ってコマンドを作りました。

導入と使い方

go get github.com/skanehira/fkもしくはreleasesからバイナリをダウンロードしてください。

使い方は fk を実行するだけです。 fk を実行するとあいまい検索できる状態になるので、任意の単語を入力して、CTRL-iで選択します。 Enterで選択済みのプロセスをkillします。

キーバインドは次になります。

keydescription
CTRL-iselect/unselect
CTRL-jgo to next
CTRL-kgo to prev
CTRL-cabort
Enterkill

しくみ

あいまい検索のUIはgo-fuzzyfinderというライブラリを使っています。 こちらのライブラリはfzfと似たインタフェースを持っていてかつとてもシンプルですので、GoでfzfのようなUIを使いたい場合はぜひ使ってみてください。

プロセス一覧はgo-psというライブラリを使っています。このライブラリでプロセスIDとコマンド名を取得できるので、それをgo-fuzzyfinderに渡します。

メインの処理は次の部分になります。

func processes() ([]process, error) {
	var processes []process
	procs, err := ps.Processes()
	if err != nil {
		return nil, err
	}

	for _, p := range procs {
		// skip pid 0
		if p.Pid() == 0 {
			continue
		}
		processes = append(processes, process{
			Pid: p.Pid(),
			Cmd: p.Executable(),
		})
	}

	return processes, nil
}

func main() {
	...
	procs, err := processes()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	idx, err := fuzzyfinder.FindMulti(
		procs,
		func(i int) string {
			return fmt.Sprintf("%d: %s", procs[i].Pid, procs[i].Cmd)
		},
	)
	...

	for _, i := range idx {
		pid, cmd := procs[i].Pid, procs[i].Cmd
		fmt.Println(pid, cmd)

		if err := kill(pid); err != nil {
			fmt.Fprintln(os.Stderr, err)
		}
	}

}

おわり

小さなツールですが、プロセスをkillする面倒さから開放されます。 ぜひ試してみてください


Go

2020/05/24 00:00