Linux pkill 命令:按模式批量杀死进程的原理与实践
摘要pkill是 Linux 下基于进程名或正则表达式批量管理进程的高效命令。本文从pkill与kill、killall的区别讲起覆盖基本用法、-f命令行匹配、按用户/终端过滤、信号控制、pgrep查询搭档、底层实现原理及安全注意事项帮助你安全高效地管理服务器进程。用过 Linux 的人大概都经历过这种场景服务器上跑了一堆同名进程你想把它们全部杀掉结果只能ps aux | grep xxx找 PID然后一个一个kill。效率低不说还容易漏杀。pkill就是专门解决这个问题的。它允许你用进程名或正则模式来匹配进程一条命令就能批量处理。pkill vs kill vs killall先理清三者的关系很多人容易搞混命令匹配方式典型用法killPIDkill 1234killall进程名精确匹配killall nginxpkill进程名正则匹配pkill -f node.*serverkill最基础只能用 PID。killall进了一步支持进程名但它是精确匹配不支持正则。pkill则是最灵活的底层基于正则表达式引擎支持模式匹配。基本用法最简单的用法——按进程名杀死# 杀死所有名为 nginx 的进程pkillnginx# 杀死所有 node 进程pkillnode注意pkill默认匹配的是进程名的前缀和子串不是精确匹配。比如pkill ssh会同时匹配sshd、ssh-agent等进程。如果需要精确匹配加-x参数# 只杀死名为 ssh 的进程不影响 sshdpkill-xssh-f 参数匹配完整命令行这是pkill最强大的功能。默认情况下pkill只匹配进程名通常是可执行文件名但很多时候你需要匹配命令行参数。# 杀死所有 node server.js 进程pkill-fnode server.js# 杀死所有运行在 3000 端口的 node 进程pkill-fnode.*3000# 杀死所有 python 脚本中包含 crawl 的进程pkill-fpython.*crawl-f让 pkill 去匹配/proc/pid/cmdline中的完整命令行而不仅仅是进程名。按用户和终端过滤# 杀死用户 www 运行的所有 nginx 进程pkill-uwww nginx# 杀死在 pts/0 终端上运行的所有 python 进程pkill-tpts/0 python# 组合使用杀死用户 deploy 在 pts/1 上的所有进程pkill-udeploy-tpts/1-u支持用户名和 UID还可以用!取反# 杀死所有非 root 用户的 node 进程pkill-u!rootnode信号控制pkill默认发送SIGTERM信号 15这是优雅终止信号。你可以用-signal指定其他信号# 强制杀死SIGKILL信号 9pkill-9nginx# 重新加载配置SIGHUP信号 1pkill-HUPnginx# 挂起进程SIGSTOPpkill-STOPnode# 恢复进程SIGCONTpkill-CONTnode实际工作中推荐先用SIGTERM等几秒再SIGKILL# 先优雅终止pkill-TERMnginxsleep3# 还没死就强杀pkill-9-xnginxpgreppkill 的查询搭档pgrep和pkill共享同一套匹配逻辑区别是pgrep只查询不杀进程# 查找所有 node 进程的 PIDpgrepnode# 查找并显示进程名pgrep-lnode# 查找并显示完整命令行pgrep-anode# 查找匹配进程的数量pgrep-cnode一个实用的组合先确认再操作# 先看有哪些匹配的进程pgrep-afpython.*worker# 确认无误后杀死pkill-fpython.*worker实现原理pkill 底层做了什么pkill的核心逻辑其实不复杂大致流程如下1. 读取 /proc 目录下所有数字子目录每个目录对应一个进程 2. 对每个进程读取 /proc/pid/stat 获取进程名 3. 如果指定了 -f额外读取 /proc/pid/cmdline 获取完整命令行 4. 用正则表达式匹配进程名或命令行 5. 如果匹配成功调用 kill(pid, signal) 发送信号用 Python 模拟核心逻辑importosimportreimportsignaldefpkill(pattern,full_matchFalse,sigsignal.SIGTERM):regexre.compile(pattern)forpid_dirinos.listdir(/proc):ifnotpid_dir.isdigit():continuepidint(pid_dir)try:iffull_match:# 读取完整命令行withopen(f/proc/{pid}/cmdline,rb)asf:cmdlinef.read().replace(b\x00,b ).decode(utf-8,errorsignore)targetcmdlineelse:# 读取进程名stat 文件的第二个字段withopen(f/proc/{pid}/stat)asf:statf.read()targetstat.split())[0].split(()[1]ifregex.search(target):os.kill(pid,sig)print(fKilled{pid}:{target})except(PermissionError,FileNotFoundError,ProcessLookupError):continue这段代码展示了pkill的本质遍历/proc、正则匹配、发送信号。安全注意事项pkill的正则匹配是一把双刃剑。几个常见坑1. 不要用太宽泛的模式# 危险会杀死所有包含 java 的进程pkilljava# 更安全精确匹配pkill-xjava# 或更精确的模式pkill-fjava -jar myapp.jar2. 先用 pgrep 预览# 养成好习惯先 pgrep -a 看看会匹配到什么pgrep-afnode3. 避免误杀自身pkill不会杀死自己但可能杀死同名的其他脚本。用-o最老的和-n最新的可以精确控制# 只杀死最老的 node 进程pkill-onode# 只杀死最新的 node 进程pkill-nnode小结pkill是 Linux 进程管理中非常实用的命令核心优势在于正则模式匹配和完整命令行匹配-f。配合pgrep做预览可以安全高效地管理服务器上的进程。更多 Linux 命令参考可以查看 Linux 命令参考。相关工具Linux kill 进程管理命令 | Linux ps 进程监控命令