linux顽固进程查看并清理
我遇到的情况是这样的,我的问题是这个我应该如何处理呢,为什么kill不生效呢,ps出来的这些量应该如何解读
> ./excute/get_input
控制系统准备完成,开始执行任务---------------------------------
是否初始化场景?(y/n) : y
初始化中,请等待...
---------------------------------控制系统准备完成,开始执行任务---------------------------------
是否初始化场景?(y/n) : ^C^C^C^C^C^C^C^C^C^C^C^C^Z
[3] + 256344 suspended ./excute/get_input
> ps -aux | grep get_input
tipriest 237255 0.0 0.0 366500 12316 pts/8 Tl 22:25 0:01 ./excute/get_input
tipriest 243278 0.0 0.0 366500 12356 pts/8 Tl 22:27 0:02 ./excute/get_input
tipriest 256344 2.3 0.0 366500 12300 pts/8 Tl 22:33 1:06 ./excute/get_input
tipriest 403982 0.0 0.0 12124 2696 pts/8 S+ 23:21 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox --exclude-dir=.venv --exclude-dir=venv get_input
> kill 403982
kill: kill 403982 failed: no such process
好的,这是一个非常经典的 Linux/Unix 命令行操作问题,很多新手都会遇到。我们来一步步拆解分析,你就能完全明白发生了什么,以及如何正确处理。
核心问题:为什么 kill 403982
不生效?
简短回答: 因为你试图 kill
的是 grep
命令本身,而不是你的目标程序 get_input
。而 grep
命令执行得非常快,在你看到它的 PID (403982) 并输入 kill
命令时,它早就已经执行完毕并退出了。所以系统会告诉你“no such process”(没有这个进程)。
详细分析与解读
我们来详细分析你提供的每一步操作和输出。
1. 运行与中止程序
> ./excute/get_input
...
是否初始化场景?(y/n) : ^C^C^C^C^C^C^C^C^C^C^C^C^Z
[3] + 256344 suspended ./excute/get_input
^C
(Ctrl+C): 这是发送SIGINT
信号,意为“中断”进程。通常程序会捕捉这个信号并优雅地退出。但你的程序似乎没有响应(可能程序代码忽略了此信号,或者陷入了无法中断的循环)。^Z
(Ctrl+Z): 这是发送SIGTSTP
信号,意为“暂停”或“挂起”(suspend)进程。它会将当前在前台运行的进程放到后台并暂停。[3] + 256344 suspended ...
: 这是 shell 给你的反馈。[3]
: 这是这个任务(job)在当前 shell 中的编号,叫做 Job ID。256344
: 这是这个进程的进程ID (PID)。suspended
: 状态是“已挂起”。
2. 查看进程 ps -aux | grep get_input
这个命令分为两部分,通过管道 |
连接:
ps -aux
: 列出系统上所有用户的所有进程的详细信息。grep get_input
: 从ps
的输出中,过滤出包含 “get_input” 字符串的行。
你的输出是:
tipriest 237255 0.0 0.0 366500 12316 pts/8 Tl 22:25 0:01 ./excute/get_input
tipriest 243278 0.0 0.0 366500 12356 pts/8 Tl 22:27 0:02 ./excute/get_input
tipriest 256344 2.3 0.0 366500 12300 pts/8 Tl 22:33 1:06 ./excute/get_input
tipriest 403982 0.0 0.0 12124 2696 pts/8 S+ 23:21 0:00 grep --color=auto ... get_input
如何解读 ps -aux
的输出列:
USER
: 运行该进程的用户 (tipriest
)。PID
: 进程ID (Process ID)。这是系统的唯一标识符,是kill
命令需要的目标。%CPU
: CPU使用率。%MEM
: 内存使用率。VSZ
: 虚拟内存大小 (KB)。RSS
: 物理内存大小 (KB)。TTY
: 进程运行所在的终端 (pts/8
表示一个伪终端)。STAT
: 进程状态。这个非常重要!T
: Traced or stopped (被跟踪或已停止/挂起)。你的3个get_input
进程都是这个状态,因为你之前用了Ctrl+Z
。l
: multi-threaded (多线程进程)。所以Tl
表示一个被挂起的多线程进程。S
: Interruptible sleep (可中断的睡眠,通常在等待某个事件)。+
: In the foreground process group (属于前台进程组)。R
: Running or runnable (正在运行或可运行)。
START
: 进程启动时间。TIME
: 进程已经占用的CPU总时间。COMMAND
: 启动进程的命令。
分析你的进程列表:
- PID
237255
,243278
,256344
: 这三个都是你的目标程序./excute/get_input
。它们的状态是Tl
(已挂起),说明你之前可能运行并用Ctrl+Z
挂起了它们三次。 - PID
403982
: 看COMMAND
列,这是grep ... get_input
命令本身。它被ps
列出来,仅仅是因为在ps
运行的那一瞬间,grep
也在运行。
3. 失败的 kill
命令
> kill 403982
kill: kill 403982 failed: no such process
你拿 grep
进程的 PID (403982
)去执行 kill
。如前所述,grep
进程生命周期极短,在你输入 kill
时它早已结束。所以系统找不到这个进程了,操作自然失败。
正确的处理方法
你的目标是杀掉那3个已经挂起的 get_input
进程。你有以下几种方法:
方法一:使用正确的 PID 进行 kill
(推荐)
从 ps
的输出中找到 get_input
进程的 PID,然后 kill
它们。
# 你可以一次性 kill 掉所有相关的进程
kill 237255 243278 256344
如果 kill
不生效怎么办?
kill
默认发送的是 SIGTERM
(15) 信号,是比较“礼貌”的终止请求。如果程序不响应(就像它不响应 Ctrl+C
一样),你可以使用“强制”信号 SIGKILL
(9)。
# -9 代表 SIGKILL 信号,强制终止
kill -9 237255 243278 256344
注意: kill -9
应当作为最后的手段,因为它不会给程序任何清理现场(如保存文件)的机会。
方法二:使用 pkill
或 killall
(更方便)
如果你想杀掉所有名为 get_input
的进程,不必一个一个找 PID。
# pkill 会根据进程名来查找并杀死进程
pkill get_input# 如果 pkill 不生效,同样可以加 -9
pkill -9 get_input
或者使用 killall
(功能类似):
killall get_input
killall -9 get_input
方法三:管理 Shell 任务 (Job)
因为你使用了 Ctrl+Z
,这些进程现在是你的 shell 的 “jobs”。你可以用 jobs
命令查看它们:
> jobs
[1] - suspended ./excute/get_input
[2] - suspended ./excute/get_input
[3] + suspended ./excute/get_input
(这里的 job ID [1], [2], [3] 只是示例)
然后你可以通过 job ID (%
后面跟数字) 来操作它们:
# 杀死 job ID 为 3 的任务
kill %3# 如果需要,也可以强制杀死
kill -9 %3# 你也可以把任务重新调回前台(然后再次尝试 Ctrl+C)
fg %3
总结
ps ... | grep xxx
命令会把grep
进程自身也显示出来。要kill
进程,请确保你选择的是目标程序的 PID,而不是grep
的 PID。Ctrl+C
(中断) 和Ctrl+Z
(挂起) 是不同的。你的程序忽略了前者,但响应了后者。- 要终止顽固进程,首先尝试
kill <PID>
,如果无效,再使用kill -9 <PID>
。 - 为了方便,使用
pkill <进程名>
或killall <进程名>
是批量杀死同名进程的好方法。