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: k
Unknown 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
为了更精确,我还会在脚本中使用 tcp
和 lsof -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的进程? [复制]的主要内容,如果未能解决你的问题,请参考以下文章