【问题标题】:shell script to kill the process listening on port 3000? [duplicate]shell脚本杀死监听端口3000的进程? [复制]
【发布时间】:2012-02-28 10:00:07
【问题描述】:

我想定义一个名为 kill3000 的 bash 别名来自动执行以下任务:

$ lsof -i:3000

COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
ruby    13402 zero    4u  IPv4 2847851      0t0  TCP *:3000 (LISTEN)

$ kill -9 13402

【问题讨论】:

  • 为什么要别名而不是 bash 函数?
  • 我会创建一个函数,首先执行 kill -TERM 然后执行 kill -KILL 因为在不给进程正确终止的机会的情况下终止进程是不合适的......
  • @SteveChambers 在链接到的答案之前编写它时,这是如何重复的?荒谬……

标签: linux bash sockets kill


【解决方案1】:
alias kill3000="fuser -k -n tcp 3000"

【讨论】:

  • 之所以选择这个作为答案是因为我后来发现lsof -i:3000可以在我在web浏览器中访问服务器时带回多个进程(例如):ruby 587 zero 10u IPv4 2239530 0t0 TCP localhost:3000->localhost:45341 (ESTABLISHED) firefox 26843 zero 63u IPv4 2238948 0t0 TCP localhost:45337->localhost:3000 (ESTABLISHED)我发现, fuser -n tcp 3000 最准确地带回了原始过程,因此可能是最可靠的使用方法。
  • 我注意到的一件事是 fuser 不区分本地和远程连接 - 所以我认为如果您曾经有一个进程连接到远程端口 3000,它也会被杀死。物有所值。
  • 请注意,fuser 默认发送 SIGKILL。您可以告诉它使用不同的信号,例如:fuser -k -TERM -n tcp 3000
  • 出于某种原因,这对我不起作用。在我发出命令并执行 netstat -tulpn | 之后grep 8001 ,我仍然得到进程的pid。我试图杀死一个 tcp 端口监听进程 - fuser -k -n tcp 8001
  • 不适用于 OSX:Unknown option: kUnknown option: n
【解决方案2】:

试试这个:

kill -9 $(lsof -i:3000 -t)

-t 标志是您想要的:它显示 PID,仅此而已。

更新

如果找不到进程并且您不想看到错误消息:

kill -9 $(lsof -i:3000 -t) 2> /dev/null

假设您正在运行 bash。

更新

Basile's suggestion 很好:我们应该首先尝试正常终止进程将kill -TERM,如果失败,则kill -KILL(又名kill -9):

pid=$(lsof -i:3000 -t); kill -TERM $pid || kill -KILL $pid

您可能希望将其设为 bash 函数。

【讨论】:

  • 我会先推荐kill -TERM,然后是kill -KILL
  • 为了更精确,我还会在脚本中使用 tcplsof -i tcp:3000
【解决方案3】:

使用原始lsof 命令的另一个选项:

lsof -n -i:3000 | grep LISTEN | awk '{ print $2 }' | uniq | xargs kill -9

如果您想在 shell 脚本中使用它,您可以将 -r 标志添加到 xargs 以处理没有进程正在侦听的情况:

... | xargs -r kill -9

【讨论】:

  • 不要忘记 xargs 上的 -r。 :p
  • synthesizerpatel:我个人不太关心not enough arguments 消息。如果没有输入,kill 不会发疯并拍摄您的初始化进程(如果我错了,请纠正我;)
  • 如果你在shell脚本中有这样的东西,带有'set -e',或者'#!/usr/bin/bash -e',kill失败会导致整个脚本失败.我的座右铭是:如果可以,悄悄地成功,如果必须,优雅地失败 - 但总是返回有用的退出代码。
  • @synthesizerpatel:是的,但如果我只在命令行中使用它(“自动化例程”),我实际上想看看是否有东西被杀死,这是一个实现这一点的简单方法 :) 在 shell 脚本中,我可能会添加 -r 或使用 || true,所以我至少可以看到错误消息。
  • 嘿。我只遇到过这个,因为我测试了 lsof 版本。如果您有绑定到多个接口的服务,则 lsof 方法也会产生两个相同的 PID。我不是在挑剔你——我向上帝发誓。以前从未见过 lsof -i:NNNN 标志。哦,我建议的另一件事是'-n',这样 lsof 就不会尝试反向查找任何主机。
【解决方案4】:

怎么样

alias kill3000="lsof -i:3000 | grep LISTEN | awk '{print $2}' | xargs kill -9"

【讨论】:

    【解决方案5】:

    fuser -k 3000/tcp 也应该可以工作

    【讨论】:

      【解决方案6】:
      fuser -n tcp 3000
      

      将产生的输出

      3000/tcp:     <$pid>
      

      所以你可以这样做:

      fuser -n tcp 3000 | awk '{ print $2 }' | xargs -r kill
      

      【讨论】:

      • 我很确定awk 的这种用法是不必要的并且无论如何都会失败。使用fuser 输出,我最终意识到第一列实际上是stderr。
      猜你喜欢
      • 1970-01-01
      • 2016-05-20
      • 2016-07-08
      • 2013-03-26
      • 2012-09-30
      • 2013-11-11
      • 1970-01-01
      • 2016-05-04
      相关资源
      最近更新 更多