无法终止任务管理器中正在运行但似乎不可见的进程

无法终止任务管理器中正在运行但似乎不可见的进程

我启动了一个无法运行的应用程序,但我无法删除它,因为它仍在运行。我可以打印 PID,但无法终止使用它的进程。

~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process

答案1

您是否注意到,两次尝试中您得到了两个不同的 PID?

考虑一下:如果您输入类似 的命令vi raven.txtps ax则将显示一行显示 的命令vi raven.txt。同样,如果您输入类似 的命令grep snapprps ax则将显示一行显示 的命令。并且,如果您通过grep snappr管道传输该命令的输出,则将找到该行psgrep snapprgrep那就是自我描述。因此,如果你输入

$ ps ax | grep snappr | awk '{print $1}'

重复执行此操作,每次它都会打印一个不同的数字(因为它打印的是 PID ,并且每次运行命令时grep都会得到一个新的、唯一的进程)。grep

最后,请考虑:kill只有在知道命令的参数后才能执行该命令。要知道命令的参数,管道$(ps ax | grep snappr | awk '{print $1}')必须已完成。这意味着 必须grep已终止1。因此,kill被赋予了进程的 PID grep,但只有在grep进程终止后才会被赋予 PID —— 因此,它自然会报告“没有这样的进程”。

也许我应该提到没有snappr进程正在运行。如果有,您的第一个命令将输出两个数字:的 PIDsnappr和 的 PID grep snappr。现在,如果snappr正在运行,您的命令可能会开始半正确运行,我的意思是它会执行您想要的操作,但也会给出错误消息。如果 正在snappr以 PID 42097 运行,并且grep snappr以 PID 70848 运行,则kill命令将是kill 42097 70858,这将终止snappr 并收到错误消息,因为尝试终止grep不再存在的进程。

您可能想要改进这一点。我最喜欢的方法是将 改为grepgrep "[s]nappr"这样可以匹配snappr但不会匹配自身。另一种方法是使用pgrep而不是ps | grep


1或者,awk如果grep仅关闭其 stdout,则可完成。这对于 *nix 程序来说是非常不寻常的行为。

答案2

简短答案

不要跳过 Bash 圈来杀死snapprpsgrep然后通过管道awk再通过管道。相反,尝试像这样杀死它pkill;没有混乱或麻烦,它基于开箱即用的流程名称进行定位:

sudo pkill snappr

较长的答案

不太清楚如何鲷鱼在系统进程级别运行,但问题可能是您只获取子进程 ID 而不是父进程 ID。

事实上,我相信你用来获取进程 ID 的方法 ( ps ax | grep snappr | awk '{print $1}') 将返回与之连接的整个进程 ID 列表,snappr无论它是父进程还是子进程。因此,使用该方法,你可能杀死一个仅仅是子进程 ID 的进程 ID,但父进程 ID 仍然处于活动状态,并且能够“生成”另一个子进程进行补偿。

因此,也许您可​​以做这样的事情来获取您输入的任何进程 ID 的最终父 ID 并对其采取行动;关于其工作原理的简单概念证明:

ps -p [process ID] -o ppid=

在 Bash 中运行该裸命令将为您提供输入的子进程 ID 的父进程 ID [process ID]。因此,如果子 ID4567的父进程 ID 为,123则命令将是:

ps -p 4567 -o ppid=

那将会返回123

话虽如此,但这可能是一种处理离群进程的危险方式,因为如果您的脚本获取了 的实际父进程 ID snapper,那么该进程 ID 的父进程实际上可能是您自己的 Bash shell。因此,您可能会无意中杀死您的 Bash shell,而不是将snapper您从系统中剔除,同时让snapper进程继续运行。

但话虽如此,为什么不让你的生活更轻松一点,直接跑步pkill像这样:

sudo pkill snappr

这将终止所有连接的进程,snappr无需任何复杂的命令行操作。

相关内容