为什么“kill -9”会杀死浏览器和服务器?

为什么“kill -9”会杀死浏览器和服务器?

有时我必须使用kill -9作为最后手段来终止我的 Rails 服务器。不幸的是,我必须经常这样做,以至于我在 bash_profile 中编写了一个辅助函数来执行此操作。

如果我手动执行此操作 -- ps aux | grep '[r]ails],获取 pid (例如12345),并且kill -9 12345-- 它会杀死服务器并保持浏览器完好无损。但我的函数也杀死了浏览器,这是我不想做的:

function running {
  ps -p $(lsof -i :3000 -t) &> /dev/null
}

function k9 {
  if running
  then
    kill -9 $(lsof -i :3000 -t)
  else
    echo "Rails server is not running"
  fi
}

我已经确认lsof -i :3000 -t获取的 pid 与我获取的 pid 相同ps aux,那么我做错了什么?

答案1

问题:

使用lsof -i :3000 -t,您将查找连接到端口 3000 的任何进程,该端口可能位于偏僻的边。

在使用脚本的情况下,浏览器似乎在端口 3000 上连接到 Rails 服务器。区别在于使用浏览器和使用kill.

这意味着浏览器被列在太的输出中lsof,并被杀死。

您应该更好地终止类似于您的 Rails 服务器的进程,而不是本地或其他地方使用端口 3000 的任何进程。


一般解决方案:

pkill是个正确的工具为了工作。
为了匹配什么,使用pgrep,其匹配方式相同:

如果服务器的命令行(如 ps 所示)以命令名称标识您的服务器实例,您可以使用pkill servercommand.
如果您需要匹配一部分命令行参数,添加-f,例如pkill -f serverargument

被杀死的进程pkill将仅被列出pgrep- 所以用它来尝试将被杀死的进程。添加选项-apgrep列出命令行,而不仅仅是 pid。


pgrep / pkill 的示例:

作为使用的示例-f:根据ps,这两个实例xbindkeys正在运行:

$ ps aux|grep '[x]bindkeys'
26719 ?        S      0:00 xbindkeys -f /tmp/xbindkeysrc-tmp
32046 ?        S      0:00 xbindkeys -f /home/auser/.xbindkeysrc

现在我可以通过以下方式找到这两个实例:

$ pgrep xbindkeys
26719
32046

或者显示命令:

$ pgrep -a xbindkeys
26719 xbindkeys -f /tmp/xbindkeysrc-tmp
32046 xbindkeys -f /home/auser/.xbindkeysrc

或者通过命令行参数匹配实例之一:

$ pgrep -f '/home/auser/.xbindkeysrc'
32046

如果没有-f,则没有任何进程匹配:

$ pgrep '/home/auser/.xbindkeysrc'

最后,向进程发送信号,例如kill

$ pkill -f '/home/auser/.xbindkeysrc'


基于原始方法的替代解决方案:

解决方案pkill更加通用,但是要遵循您原来的方法,lsof可以使用命令更严格匹配
“侦听该端口的任何本地服务器”,
而不是
“以任何方式使用本地端口的任何程序,或以任何方式使用该号码的远程端口的任何程序”。

该选项-sTCP:LISTEN将列表限制为侦听的端口,并且由于只能侦听本地端口,因此也只能侦听本地端口。

它可以用作if这样的测试:

if lsof -i :3000 -sTCP:LISTEN -t >/dev/null ; then
    echo running
else
    echo not running
fi



关于使用 SIGKILL 的旁注,如 Kill -9 中所示:

KILL 信号的使用方式与pkill以下相同kill

$ pkill -9 -f '/home/auser/.xbindkeysrc'

但在大多数情况下,这比默认信号没有任何优势-15,并且在某些情况下,它会破坏一些东西。所以让它成为一种习惯并不是一个好主意。

看一眼我什么时候不应该杀死-9进程?了解为什么您不想使用-9默认值。

相关内容