在Mac上查找(并终止)锁定端口3000的进程

2951

如何查找(并终止)监听/使用我的TCP端口的进程?我在macOS上。

有时,在崩溃或某些错误之后,我的Rails应用程序会锁定端口3000。我无法使用 ps -ef 找到它...

运行时

rails server

我得到了

Address already in use - bind(2) (Errno::EADDRINUSE)

当停止Node.js进程时,会出现相同的问题。即使进程已经停止并且应用程序停止运行,端口3000仍然被锁定。再次启动应用程序时,会得到以下提示:
Address already in use (Errno::EADDRINUSE)

42
下面是@Kevin Suttle在下面的回答中提供的一种非常简洁的解决方案,可以用来终止任何用户指定端口上的进程。此处为了保存记录而复制:function killport() { lsof -i TCP:$1 | grep LISTEN | awk '{print $2}' | xargs kill -9 } - user456584
@user456584 上面的评论应该被接受为答案 ^^^ 那个函数可以用来终止我在一个端口上运行的_许多_进程。 - Andrew Bowman
通过使用netstat查找进程并使用kill -9命令终止进程后,程序可以正常工作! - Gaurav
19
@richardec 的命令 kill -9 $(lsof -ti:3000) 无效吗? - Abhijith Sasikumar
这显然是一个非常具体的编程问题,很多人都会经常在谷歌上搜索。我需要找出在某个端口上运行的是什么,以便重新启动我的网络应用程序。我不认为它应该被关闭。请投票重新开放。 - superluminary
显示剩余3条评论
40个回答

4594
  1. 你可以尝试使用netstat

netstat -vanp tcp | grep 3000
  • 如果您使用的是 macOS El Capitan 或更新版本(或者您的 netstat 不支持 -p),请使用 lsof 命令。

  • lsof -i tcp:3000
    

    54
    谢谢!你的回答激发了我撰写"death_to 'port'"脚本的灵感。(#!/usr/bin/rubylsof -t -i tcp:#{ARGV.first} | xargs kill - Sv1
    329
    lsof命令中的"terse"标志可生成适合管道传递给后续kill命令的输出:lsof -t -i tcp:1234 | xargs kill - Manav
    19
    我已将以下内容放入我的~/.bash_profile文件中:findandkill() { port=$(lsof -n -i4TCP:$1 | grep LISTEN | awk '{ print $2 }') kill -9 $port } alias killport=findandkill,因此现在我只需要输入killport 8080就可以为我节省一些时间。 - Alfonso Embid-Desmet
    9
    另一个提示是在lsof命令中添加-P参数,以便在输出中显示原始端口:lsof -P -i:3000 - Jason Axelson
    27
    这篇帖子只回答了一半的问题。 - png
    显示剩余11条评论

    3236

    查找:

    sudo lsof -i :3000
    

    击杀:

    kill -9 <PID>
    

    请注意:-9 立即结束进程,不给予其清理自身的机会。这可能会引起问题。考虑使用 -15(TERM)或 -3(QUIT)进行更加温和的终止,以允许进程在自身清理之后结束。


    96
    有时候执行 lsof -i :port 命令会没有任何输出,可以尝试使用 sudo lsof -i :port 命令。 - kilik52
    68
    为了安全起见,建议在尝试“-9”之前,先尝试使用“kill -15 <PID>”命令。 - Jamon Holmgren
    26
    @MichaelTrouw,虽然已经过去了近一年,但这是您的答案。 :-) http://unix.stackexchange.com/a/8918 简而言之,kill -15 给进程一个机会来清理自己。 - Jamon Holmgren
    30
    我认为这个回答应该说明 -9 的作用。 - Joseph Fraley
    19
    请不要轻易使用 kill -9 命令,先尝试其他信号。该命令会立即终止进程,而不会进行清理工作,可能会留下混乱或使数据库状态不一致的问题。建议首先尝试 TERM 信号(默认为 kill,无需标志)或 QUIT 信号(kill -3 pid),并在发送 KILL 信号之前确认您要处理的进程。 - niels
    显示剩余12条评论

    1102

    快速且最简单的解决方案:

    kill -9 $(lsof -ti:3000)
    

    对于多个端口:

    kill -9 $(lsof -ti:3000,3001)
    

    #3000 是要释放的端口

    使用单行命令杀掉多个端口:

    kill -9 $(lsof -ti:3000,3001)
    

    #这里的3000和3001是需要释放的端口

    lsof -ti:3000

    如果端口已经被占用,以上面的命令会返回类似于这样的结果:82500 (进程ID)

    lsof -ti:3001

    82499

    lsof -ti:3001,3000

    82499 82500

    kill -9 $(lsof -ti:3001,3000)

    该命令可以一次终止82499和82500两个进程。

    package.json脚本中使用:

    "scripts": {
       "start": "kill -9 $(lsof -ti:3000,3001) && npm start"
    }
    

    在终端中,您可以使用:

    npm run start
    

    5
    这应该是最佳方案。使用一个简短的命令,既可以查找又可以杀死:) - Dotl
    当端口空闲时,我会收到“kill: not enough arguments”的错误信息。是否有可能使其在端口被占用和空闲时都能正常工作? - Dan Yishai
    尝试:$(lsof -ti:3000) && kill -9 $(lsof -ti:3000) - Abhijith Sasikumar
    1
    根据此处的回答,我创建了tap:brew tap devasghar/portkill && brew install devasghar/portkill/homebrew-portkill 然后你可以这样做:portkill 3000,对于多个端口,则使用如下命令:portkill 3000,3001 - devasghar
    我尝试了这个一行命令但是我得到了以下信息:kill: 参数不足 - Yvan Rugwe
    显示剩余3条评论

    314

    以上所有方法对我都无效。有跟我一样经历的人可以尝试以下方法(这个方法适用于我):

    运行:

    lsof -i :3000 (where 3000 is your current port in use)
    

    然后检查报告的PID的状态:

    ps ax | grep <PID>
    

    最终,"摆脱它":

    kill -QUIT <PID>
    

    34
    实际上,这个答案似乎比Filip Spiridonov更晚得到的答案更好,后者获得了277个赞,而您的答案只有9个。您的答案早了6个月,并且提供了与后者相同但稍微更详细的信息。真是不公平啊... - Floris
    2
    在执行 kill -QUIT 命令之前,尝试使用 kill -TERM(或者只用 kill)命令。并不是每个进程都会在收到 SIGQUIT 信号时进行有序关闭。 - craig65535

    205

    这个单行命令很容易记住:

    npx kill-port 3000

    你也可以同时关闭多个端口:

    npx kill-port 3000 3001 3002

    如果需要更强大的带搜索功能的工具:

    npx fkill-cli


    备注:它们使用第三方JavaScript包。 npx是Node.js内置的。

    来源:推特 | Github


    你能分享一下使用brew安装npx的详细步骤吗?我尝试在我的Mac High Sierra 10.13.3上安装它,但是无法工作。 - realPK
    1
    @realPK npx 是随 npm 一起提供的,而 npm 又是随 node.js 一起提供的,因此它不是一个独立的软件包。只需升级您的 node.jsnpm 版本即可。 - Bruno Lemos
    我主要做Java,还没有接触过Node。我找到了一种不同的杀死端口上运行的服务的方法。谢谢你的回复。 - realPK
    13
    需要使用NodeJS和JavaScript来终止在端口3000上运行的某些东西,可能是Rails... 对我来说似乎太繁琐了。 在你的.bashrc或.zshrc文件中添加一个简单的别名行即可解决问题,无需联网。alias kill3000='lsof -ti:3000 | xargs kill'然后你可以执行:kill3000 - Khalil Gharbaoui
    1
    运行完美无缺! - Gaurav

    199
    一行代码用于提取使用端口3000的进程的PID并终止它。
    lsof -ti:3000 | xargs kill
    

    -t标志从lsof输出中除了PID之外的所有内容,使得杀死进程变得容易。

    14
    您可以使用以下命令过滤出“监听”端口:lsof -ti:3000 -sTCP:LISTEN - Zlemini
    2
    这种方法对我来说效果最好。一条简单的代码,清除了忙碌的端口。谢谢! - Ryan Trainor
    1
    我根据这个添加了一些函数到我的配置文件中port-kill() { lsof -ti :"$1" | xargs kill -9; } # 给进程一个优雅退出的机会 port-quit() { lsof -ti :"$1" | xargs kill -QUIT; } - What Would Be Cool

    170
    您可以使用lsof -i:3000 命令。 这是“列出打开的文件”命令,它会给您一个进程列表以及它们使用的文件和端口。

    这是一个很好的方法,你能否更新你的答案,包括最简单的杀死命令的方式? - CWSites

    81

    要强制结束这样的进程,请使用以下命令

    lsof -n -i4TCP:3000  
    
    OR lsof -i:3000
    

    3000是进程运行的端口号

    这将返回进程ID(PID)并运行

    kill -9 "PID"
    

    将PID替换为运行第一个命令后得到的数字

    例如,如果我想要结束在端口8080上运行的进程

    为什么kill -9 PID无法生效?如果你试图用PID结束一个进程,但它仍然在另一个PID上运行,那么看起来你已经在不同的账户(很可能是root账户)中启动了该进程。所以使用sudo su登录并杀死它。


    我尝试在ZSH中创建别名:alias port="lsof -n -i4TCP:$1",但出现了以下错误... 如何解决?$ port 8080 lsof: 在此中不可接受的端口规范: -i 4TCP: - fotoflo

    67
    在你的.bash_profile中,为终止3000进程创建一个快捷方式:
    terminate(){
      lsof -P | grep ':3000' | awk '{print $2}' | xargs kill -9 
    }
    

    如果被阻塞了,那么调用$terminate


    14
    你可以将此代码更加灵活以适用于任何端口:https://github.com/kevinSuttle/dotfiles/commit/9458141f40094d96952adc7c423cbdddeb909a81 - Kevin Suttle
    这是一个如此形象的名称 =p - Michael Peterson
    我有类似的东西,但是我传递了端口。我将我的函数命名为KP以用于关闭端口。 - Joseph Chambers

    63

    杀掉多个端口。

    $ npx kill-port 3000 8080 8081
    
    Process on port 3000 killed
    Process on port 8080 killed
    Process on port 8081 killed
    
    希望这可以帮到您!

    使用 npx 查找正在运行的端口怎么样? - Hazem Alabiad
    1
    Npx似乎支持检测端口,例如'npx detect-port 8080'。但似乎不支持查找所有正在运行的端口。 - Binh Ho
    1
    这是最好的,因为它很容易记住。 - ICW

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接