如何在Linux上终止运行在特定端口的进程?

1427

我尝试使用来自tomcat /bin目录的./shutdown.sh关闭Tomcat,但发现服务器未能正确关闭。因此,我无法重新启动。
我的Tomcat正在端口8080运行。

我想杀掉在8080端口运行的Tomcat进程。我首先想获取在特定端口(8080)上运行的进程列表,以便选择要终止的进程。


3
可能是与“shell脚本:如何杀掉占用3000端口的进程?”类似的问题。 - Ciro Santilli OurBigBook.com
35个回答

1700
这个 fuser 8080/tcp 命令会显示绑定在该端口上的进程的PID。
而这个 fuser -k 8080/tcp 命令会杀掉该进程。
只适用于Linux系统。更通用的方法是使用 lsof -i4(或者使用IPv6时使用 lsof -i6)。
一般形式为:
# list the TCP process bound to port PORT
fuser PORT/tcp
# Example: list the TCP process bound to port 8080
fuser 8080/tcp

# list the UDP process bound to port PORT
fuser PORT/udp
# Example: list the UDP process bound to port 8080
fuser 8080/udp

4
这是否也会关闭与8080相连的套接字? - fer y
18
它没有正确关闭端口。父进程被杀死后,端口会进入TIME_WAIT状态。然后操作系统最终会在大约60秒后完全关闭该端口。这意味着你至少要等待60秒才能重新使用该端口(除非您将重用选项提供给套接字)。 - Mark Lakata
2
在达尔文系统上,必须使用不同版本的 fuser。它只接受文件作为参数,并不支持 -k 选项。 - a p
5
"fuser -k -n tcp 8080" 命令会终止相应的进程。 - Hesham Yassin
10
@dbliss fuser是psmisc的一部分。如果你收到“fuser: command not found”的提示,需要安装psmisc。对于CentOS/RHEL 7,运行“sudo yum install psmisc”。 - Tom
显示剩余3条评论

1360

列出监听端口8080的任何进程:

lsof -i:8080

要杀死监听8080端口的任何进程:

kill $(lsof -t -i:8080)

或者更加激烈地说:
kill -9 $(lsof -t -i:8080)

(-9 对应于 SIGKILL - 立即终止/硬杀 信号:参见 Kill 信号列表kill 命令中 -9 选项的目的是什么?。如果没有指定信号给 kill,则会发送 TERM 信号,又称为 -15 或者 软杀,这有时无法完全终止一个进程)。


21
执行该命令后,我得到的输出为:“kill: 用法: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... 或者 kill -l [sigspec]”。 - Sudhir Belagali
3
@SudhirBelagali 你用超级用户 sudo 完成它了吗? - Marcel Djaman
11
在我的 Mac 上也能工作。 - asherbret
5
我想补充一点,有时候您没有权限查看进程ID,在这种情况下,您需要执行 sudo lsof -i:8080 - Akavall
4
lsof -t -i:8080 | xargs -r kill 更好地处理了空列表的情况。 - Dannie
显示剩余6条评论

381

使用命令

 sudo netstat -plten |grep java

我使用 grep java 命令,因为 tomcat 使用 java 作为它们的进程。这个命令将显示带有端口号和进程ID的进程列表。

tcp6       0      0 :::8080                 :::*                    LISTEN      
1000       30070621    16085/java

/java前面的数字是进程ID。现在使用kill命令来结束该进程。

kill -9 16085

-9 表示进程将被强制终止。


11
你可能需要补充说明,使用 netstat 获取进程名称可能需要 root 权限。 - Jonas Schäfer
2
@JonasWielicki,您可以在没有根权限的情况下查看您拥有的那些。 - abcd
我需要root权限来运行netstat。有没有办法真正知道这个进程来自哪里?据我所知,我已经关闭了所有应用程序,但可能是从一个终端窗口,我无意中将进程推到了后台任务。也许我应该先运行终端命令“ps”来查看所有进程... - JesseBoyd
即使您不知道应用程序,sudo netstat -plten | grep :8080 也可以工作。这找到了一个 lsof -i 没有为我找到的 Ruby 进程。 - MikeF
netstatss已弃用的替代品这里有一个使用它的例子。 - Pablo Bianchi
根据您的使用情况,可能存在TOCTOUC问题。 - angstyloop

356

选项1 一行代码只关闭特定端口上的LISTEN状态:

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

如果您已经安装了npm,您也可以运行以下命令:
npx kill-port 3000

18
我认为这应该是最佳答案。谢谢@Gal Bracha - Sam Kah Chiin
4
这是最佳解决方案,因为它不会使我的浏览器崩溃! - Russo
1
根据这个答案,我在 ~/.bashrc 中创建了一个函数:killp() { kill -9 $(lsof -t -i:"$1" -sTCP:LISTEN) },以便能够像这样使用它 killp 3000。(不要忘记为 {} 添加新行) - Arthur
Nit: 语法错误,多余的 **`**。 - Danny
根据使用情况可能存在TOCTOU问题。 - angstyloop

254

一行代码,省时省力

kill -9 $(lsof -t -i tcp:8080)

这里的解释是:使用lsofkill的组合。

root@localhost:~# lsof -i tcp:8080
COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
java    23672 sine  238u  IPv6 3028222      0t0  TCP localhost:http-alt (LISTEN)

选择进程ID并使用kill命令。

kill 23672

149

您可以使用lsof命令。 假设这里的端口号是8090

lsof -i:8090
该命令返回在此端口上打开的进程列表。
类似于...
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 75782 eoin 5u IPv6 0x01c1c234 0t0 TCP localhost:8090 (LISTEN)

为了释放端口,杀死正在使用该端口的进程(进程ID为75782)...

kill -9 75782

这个方法对我有用。以下是原始帖子中的链接:link


1
要强制终止进程,您需要使用-9,例如kill -9 75782;因为有时候一些进程仅使用kill命令无法终止。 - veer7

96

如果您想关闭正在运行8080端口的进程,首先需要找到8080端口进程的标识号(PID),然后将其关闭。运行以下命令查找8080端口号的PID:

sudo lsof -t -i:8080

在这里,

  • sudo - 用于请求管理员权限(用户ID和密码)的命令。
  • lsof - 文件列表(也用于列出相关进程)
  • -t - 仅显示进程ID
  • -i - 仅显示与Internet连接相关的进程
  • :8080 - 仅显示此端口号中的进程

因此,您现在可以使用以下命令轻松终止您的PID:

sudo kill -9 <PID>

在这里,

  • kill - 终止进程的命令
  • -9 - 强制终止

您可以使用以下命令来终止特定端口上的进程:

sudo kill -9 $(sudo lsof -t -i:8080)

更多内容请查看以下链接:如何在Linux上关闭特定端口上的进程


谢谢,伙计。sudo kill -9 $(sudo lsof -t -i:8080) 对我有用。 - Junaid
太棒了,这是对我有效的命令:Ubuntu - Jose Mhlanga

83

关闭特定端口上的所有进程的最佳方法:

kill -9 $(sudo lsof -t -i:8080)

不会提示输入sudo密码 - Kuldeep Yadav
1
kill命令:用法:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... 或 kill -l [sigspec]。似乎缺少-l选项,建议使用kill -l -9 $(sudo lsof -t -i:8983) - Namwanza Ronald

51

这将把运行在<port_number>上的所有进程的进程ID打印到标准输出(stdout):

fuser -n tcp <port_number> 

它还会将一些内容打印到stderr中,因此:

fuser -n tcp <port_number> 2> /dev/null

我们可以将这些进程ID提供给kill命令:


sudo kill $(fuser -n tcp <port_number> 2> /dev/null)

如果你需要频繁使用,也可以将其放在一个函数中:

function killport() {
    sudo kill $(fuser -n tcp $1 2> /dev/null)
}

45

了解特定端口上运行的服务的pid:

netstat -tulnap | grep :*port_num*

您将获得该进程的描述。现在使用kill或kill -9 pid。容易终止。

例如:

netstat -ap | grep :8080

tcp6       0      0 :::8080       :::*    LISTEN      1880/java 

现在:

kill -9 1880

请记得以 root 用户身份运行所有命令


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