shell脚本杀死监听端口3000的进程? [复制]

Posted

技术标签:

【中文标题】shell脚本杀死监听端口3000的进程? [复制]【英文标题】:shell script to kill the process listening on port 3000? [duplicate] 【发布时间】: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 在链接到的答案之前编写它时,这是如何重复的?荒谬…… 【参考方案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。

以上是关于shell脚本杀死监听端口3000的进程? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

text 在端口3000处杀死进程

shell36判断8000端口是否被占用并杀死占用端口进程

shell 杀死80端口的所有进程

如何杀死正在运行的python进程? [复制]

如何杀死一个shell脚本和它创建的进程?

在 shell 脚本中杀死后台进程