Skip to content

Instantly share code, notes, and snippets.

@Herbert8
Last active August 12, 2019 13:33
Show Gist options
  • Save Herbert8/ec815ca86dcffd3da56ecba7714bd867 to your computer and use it in GitHub Desktop.
Save Herbert8/ec815ca86dcffd3da56ecba7714bd867 to your computer and use it in GitHub Desktop.
ps aux 结合 fzf 选择进程并杀掉
#!/bin/bash
set -u
# 获取进程列表,去掉第一行
PSAUX=$(ps aux | awk '{ if (NR != 1) print $0 }')
# Linux下ps -ef和ps aux的区别及格式详解
# https://www.cnblogs.com/5201351/p/4206461.html
# 显示的字段
# USER //用户名
# %CPU //进程占用的CPU百分比
# %MEM //占用内存的百分比
# VSZ //该进程使用的虚拟內存量(KB)
# RSS //该进程占用的固定內存量(KB)(驻留中页的数量)
# STAT //进程的状态
# D //无法中断的休眠状态(通常 IO 的进程)
# R //正在运行可中在队列中可过行的
# S //处于休眠状态
# T //停止或被追踪
# W //进入内存交换 (从内核2.6开始无效)
# X //死掉的进程 (基本很少见)
# Z //僵尸进程
# < //优先级高的进程
# N //优先级较低的进程
# L //有些页被锁进内存
# s //进程的领导者(在它之下有子进程)
# l //多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads)
# + //位于后台的进程组
# START //该进程被触发启动时间
# TIME //该进程实际使用CPU运行的时间
FIELD_TITLE=('用户(USER):%s\n'
'进程ID(PID):%s\n'
'CPU 占用率(%%CPU):%s\n'
'内存占用率(%%MEM):%s\n'
'虚拟内存(VSZ KB):%s\n'
'固定内存(RSS KB):%s\n'
'终端(TTY):%s\n'
'进程状态(STAT):%s\n'
' 进程状态详情:%s\n'
'开始时间(START):%s\n'
'使用 CPU 时间(TIME):%s\n'
'命令行(COMMAND):%s')
FIELD_FORMAT=''
for A_FIELD_FMT in "${FIELD_TITLE[@]}"; do
FIELD_FORMAT="${FIELD_FORMAT}${A_FIELD_FMT}"
done
# awk 使用
# awk 入门教程 http://www.ruanyifeng.com/blog/2018/11/awk.html
# AWK 简明教程 https://coolshell.cn/articles/9070.html
# 提取预览信息
PROGRAM='{ cmdline=""; '
PROGRAM="${PROGRAM}"'statDetail=""; '
PROGRAM="${PROGRAM}"'for (i = 1; i <= length($8); i++) { '
PROGRAM="${PROGRAM}"' tmp = substr($8, i, 1); '
PROGRAM="${PROGRAM}"' if (tmp == "D") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "无法中断的休眠状态(通常 IO 的进程)"); '
PROGRAM="${PROGRAM}"' if (tmp == "R") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "正在运行可中在队列中可过行的"); '
PROGRAM="${PROGRAM}"' if (tmp == "S") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "处于休眠状态"); '
PROGRAM="${PROGRAM}"' if (tmp == "T") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "停止或被追踪"); '
PROGRAM="${PROGRAM}"' if (tmp == "W") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "进入内存交换 (从内核2.6开始无效)"); '
PROGRAM="${PROGRAM}"' if (tmp == "X") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "死掉的进程 (基本很少见)"); '
PROGRAM="${PROGRAM}"' if (tmp == "Z") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "僵尸进程"); '
PROGRAM="${PROGRAM}"' if (tmp == "<") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "优先级高的进程"); '
PROGRAM="${PROGRAM}"' if (tmp == "N") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "优先级较低的进程"); '
PROGRAM="${PROGRAM}"' if (tmp == "L") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "有些页被锁进内存"); '
PROGRAM="${PROGRAM}"' if (tmp == "s") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "进程的领导者(在它之下有子进程)"); '
PROGRAM="${PROGRAM}"' if (tmp == "l") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads)"); '
PROGRAM="${PROGRAM}"' if (tmp == "+") statDetail = sprintf(" %s\n %s ... %s", statDetail, tmp, "位于后台的进程组"); '
PROGRAM="${PROGRAM}"' for (j = 0; j < 8; j++) tmp = sprintf("%s%s", tmp, substr($8, i, 1)); '
PROGRAM="${PROGRAM}"'}'
PROGRAM="${PROGRAM}"'for (i = 11; i <= NF; i++) cmdline=sprintf("%s %s", cmdline, $i);'
PROGRAM="${PROGRAM}"'printf("'
PROGRAM="${PROGRAM}""${FIELD_FORMAT}"'", $1, $2, $3, $4, $5, $6, $7, $8, statDetail, $9, $10, cmdline) }'
# echo "${PROGRAM}"
# 用于提取预览信息的命令
preview_cmd='echo {} | awk '"'${PROGRAM}'"
# echo
# echo "${preview_cmd}"
# 选择的进程
SELECTED_PS=$(echo "$PSAUX" | fzf -e -m \
--header='进程列表' \
--bind 'ctrl-a:select-all' \
--with-nth='1,2,11..' \
--border \
--height=40% \
--preview "${preview_cmd}")
# 提取选中进程的 PID
SELECTED_PS_IDS=$(echo -e "${SELECTED_PS}" | awk '{print $2}')
# 杀掉选中进程
if [[ -n ${SELECTED_PS_IDS} ]]; then
kill $@ ${SELECTED_PS_IDS}
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment