【问题标题】:What can be causing "kill -9" to not work as expected some times?什么可能导致“kill -9”有时无法按预期工作?
【发布时间】:2019-05-04 05:38:11
【问题描述】:

我创建了一个 bash 脚本来杀死一些在运行关闭脚本后仍处于活动状态的进程。

#!/bin/sh
echo "Alive processes on" `date` ":" > $LOG_DIR/roguePs.out
ps auxww | grep 'fr_home' | grep -v 'grep' | grep -v 'stopAll.sh' >> $LOG_DIR/roguePs.out
kill -9 $(ps axww | grep 'fr_home' | grep -v 'grep' | grep -v 'stopAll.sh' | cut -d " " -f 2)
sleep 10
echo "Alive processes on" `date` ":" >> $LOG_DIR/roguePs.out
ps auxww | grep 'fr_home' | grep -v 'grep' | grep -v 'stopAll.sh' >> $LOG_DIR/roguePs.out

简单来说就是上面的脚本:

  • 列出所有包含字符串“fr_home”的进程,不包括列出进程和脚本本身的进程 (stopAll.sh)
  • 杀死所有发现的进程
  • 列出杀死后仍处于活动状态的进程

因此,脚本使用“kill -9”,有时会成功杀死所有内容,但在某些情况下,某个进程仍处于活动状态。

输出文件显示如下内容:

Alive processes on Sat May 4 12:54:15 2019 :
...
<other processes>
...
oracle  6066  0.0  0.7705128413368 ?        O   May 01  8:03 /opt/app/oracle/product/middleware/fr_home/bin/rwserver server=RptSvr_tst1 batch=yes uid=1373394053
...
<other processes>
...
Alive processes on Sat May 4 12:54:25 2019 :
oracle  6066  0.0  0.7705264421520 ?        S   May 01  8:03 /opt/app/oracle/product/middleware/fr_home/bin/rwserver server=RptSvr_tst1 batch=yes uid=1373394053

进程在杀死之前处于“O”状态(进程正在处理器中运行),之后处于“S”(睡眠)状态。永远不会处于“Z”状态(僵尸),我认为这是“kill -9”可能无法完成工作的一个可能原因。

此外,虽然进程在 10 秒后检查,但我也在几个小时后手动检查了它,它仍然存在。

不确定是什么原因导致终止无法正常工作,或者还不确定要实施什么以确保所有进程始终被终止。

任何建议将不胜感激。

【问题讨论】:

  • pid 是 pgrep 或pkill 代替ps+grep+cut
  • 是的!...这正是正在发生的事情...谢谢@Aaron。 ps+grep+cut 仅列出具有 6 位 pid 的进程。
  • 我不使用 pgrep 或 pkill 的原因是因为 Solaris 正在截断命令(有关此的更多信息:link)并且一些进程被遗漏了。如果我没有找到更优雅的解决方案,我可以使用“cut -d”“-f 3”添加第二次杀戮。远非理想,但我认为它可以完成这项工作。

标签: unix sh kill


【解决方案1】:

好的。我能够找到一个似乎对我很有效的命令。

所以,这里是评估的选项:

  • pgrep 和 pkill:首先尝试这些命令是有意义的,因为它们旨在完成我所追求的工作,并且在大多数类 Unix 操作系统中,它们可能完成这项工作。但是,此选项对我不起作用,因为命令被截断并且 pkill -f 'fr_home' 缺少一些进程。
  • 使用 awk 而不是 cut:ps axww 抛出的输出太长,因此 awk 会抛出错误消息,例如“awk: record `oracle 3553 0.1 ...' too long”。
  • 使用 gawk 代替 cut:是的,gawk(awk 的增强版本)对我有用。所以命令:
kill -9 $(ps axww | grep 'fr_home' | grep -v 'grep' | grep -v 'stopAll.sh' | cut -d " " -f 2)

成为:

kill -9 $(ps axww | grep 'fr_home' | grep -v 'grep' | grep -v 'stopAll.sh' | gawk '{print $1}')

【讨论】:

  • 所以...您可以通过单个 awk 实例避免所有 grep:ps axww | awk '/grep|stopAll\.sh/ {next} /fr_home/ {print $1}' | xargs kill -9 ... 但我认为您最好方式调整@ 987654324@ 或任何启动它以在某处记录 pid 文件,然后让您的启动/停止脚本使用它。后台启动脚本将最近后台进程的 pid 存储在 $! 中,可以将其保存到文件中。您的停止脚本可以通过在杀死任何东西之前检查那里运行的内容来验证 pidfile。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 2016-01-16
  • 2017-10-24
  • 2020-02-26
相关资源
最近更新 更多