在Mac OS X上,谁在监听指定的TCP端口?

2065

在Linux上,可以使用netstat -pntl | grep $PORTfuser -n tcp $PORT命令来查找监听特定TCP端口的进程(PID)。在Mac OS X上如何获取相同的信息?


32
抱歉,“netstat -p tcp | grep $PORT”命令无法显示进程ID,因为Mac OS X上的netstat无法显示进程ID。 - pts
29
netstat -anv 显示 Mac OS X 上的端口(来源:@SeanHamiliton 的下面解决方案)。 - Curtis Yallop
2
从上面的评论中:在 Mac OS X(10.15.7 Catalina)上,netstat -anv 命令给了我 PID。 - preOtep
19个回答

3173

在 macOS Big Sur 及更高版本中,请使用以下命令:

sudo lsof -i -P | grep LISTEN | grep :$PORT

或者只查看IPv4:

sudo lsof -nP -i4TCP:$PORT | grep LISTEN

在旧版本中,请使用以下形式之一:

sudo lsof -nP -iTCP:$PORT | grep LISTEN
sudo lsof -nP -i:$PORT | grep LISTEN

$PORT替换为端口号或逗号分隔的端口号列表。

如果需要查看低于#1024的端口信息,请在前面加上sudo(后跟一个空格)。

-n标志用于显示IP地址而不是主机名。这使命令执行速度更快,因为获取主机名的DNS查找可能很慢(对于许多主机需要几秒钟或一分钟)。

-P标志用于显示原始端口号,而不是像httpftp或更神秘的服务名称dpservesocalia之类的已解析名称。

有关更多选项,请参见注释。

出于完整性考虑,因为经常一起使用:

要杀掉PID:

sudo kill -9 <PID>
# kill -9 60401

175
在这段命令前面加上 sudo,可以查看你没有所有权的进程。 - Gordon Davisson
31
关于lion,使用更改“sudo lsof -i TCP:$PORT | grep LISTEN”进行操作。 - dhaval
63
在Mountain Lion系统中,您不需要使用grep: sudo lsof -iTCP:$PORT -sTCP:LISTEN 命令可以实现相同的功能。 - Siu Ching Pong -Asuka Kenji-
20
在经过多次搜索后,我选出了这个最好的方案。那些想要直接复制命令的人应该将$PORT替换为实际的端口号或定义变量PORT,并且对于多个端口也应该这样做,例如: export PORT=8080,4433; lsof -n -i4TCP:$PORT - siddhusingh
3
如果要调查的端口号大于1024,则无需使用sudo。 - stigkj
显示剩余8条评论

948
每个版本的 macOS 都支持这个命令:
sudo lsof -iTCP -sTCP:LISTEN -n -P
个人而言,我在我的 ~/.bash_profile 中使用了这个简单的函数:
listening() {
    if [ $# -eq 0 ]; then
        sudo lsof -iTCP -sTCP:LISTEN -n -P
    elif [ $# -eq 1 ]; then
        sudo lsof -iTCP -sTCP:LISTEN -n -P | grep -i --color $1
    else
        echo "Usage: listening [pattern]"
    fi
}

然后listening命令会列出在某个端口上监听的进程,而listening smth则会根据某个模式进行匹配。
有了这个功能,询问特定进程就很容易了,比如listening dropbox,或者端口,比如listening 22lsof命令有一些专门的选项,可以询问端口、协议、进程等等,但个人觉得上述功能更方便,因为不需要记住所有这些底层选项。 lsof是一个非常强大的工具,但可惜的是使用起来不太方便。

27
这将纳入我的dotfiles。我每隔几个月都会搜索,总是找到这个答案。 - danemacmillan
2
我认为这应该是被接受的答案,因为OP说他使用了-pntl,这将列出所有服务。而被接受的答案要求指定一个或多个端口号,这显然不是同一回事。 - seeafish
2
这对我来说在 Monterey 12.1 上也有效。 - sr9yar
对于像我这样对 Linux 不熟悉的人,你可能需要编辑 ~/.zshrc 文件以使其与 MacOS 的默认终端兼容。 - roganjosh

471

你也可以使用:

sudo lsof -i -n -P | grep TCP

这在Mavericks系统上可以使用。


4
"-i"选项使程序速度显著提升,将用时从2秒降至0.02秒。在我的应用中,这一改变产生了相当大的影响。 - Eric Boehs
这些特定的标志 -i、-n、-P 是做什么用的?我找不到确切的含义。 - Chad Watkins
我用这个命令创建了一个别名:sudo lsof -i -n -P | grep TCP | grep $PORT - alyn000r
我建议添加 "| grep $PORT" 或 "| grep LISTEN"。 - KC Baltz
太好了!在Mojave上也可以工作。 - Gefilte Fish
@ChadWatkins:-i 限制于互联网“文件” -P 提供端口号而非友好名称 -n 将提供 IP 地址而非主机名-P 和 -n 都可以使 lsof -i 运行更快。您可以使用 man lsof 获取更多信息。 - dsas

400

2016年1月更新

真的很惊讶没有人提出:

lsof -i :PORT_NUMBER

获取所需的基本信息。例如,检查端口1337:

lsof -i :1337

根据不同情况,可能会有其他变化:

sudo lsof -i :1337
lsof -i tcp:1337

你可以基于此轻松提取PID本身。例如:
lsof -t -i :1337

这个命令的结果与下面的命令等效:

lsof -i :1337 | awk '{ print $2; }' | head -n 2 | grep -v PID

快速说明:

在此输入图片描述

为了完整起见,因为通常一起使用:

杀死PID:

kill -9 <PID>
# kill -9 60401

或者作为一行代码:

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

2
该命令还会显示非监听器 PID,而问题明确要求仅显示监听器。 - pts
6
您可以运行 lsof -t -i :1338 命令。 -t 选项将返回进程 ID,因此您无需使用 awk/head 命令。 - KFunk
在El Capitan上,除了kill -9 $(lsof -t -i :5000)之外,没有任何其他方法可行。 - goksel
这太好了。在我终止它之前,我更喜欢知道那里有什么,所以(基于此),我刚刚添加到我的bashrc中:whatsonport() { ps -ef | grep \lsof -t -i :$1` }`,所以:⇒ whatsonport 3000 --> 501 14866 14865 0 6:07AM ttys006 0:01.73 node . - Sigfried
1
谢谢,lsof -i :PORT_NUMBER 对我很有帮助。 - marika.daboja

95

对于LISTEN、ESTABLISHED和CLOSED端口:

sudo lsof -n -i -P | grep TCP

只针对LISTEN端口:
sudo lsof -n -i -P | grep LISTEN

对于特定的监听端口(例如端口80):
sudo lsof -n -i -P | grep ':80 (LISTEN)'

或者如果你只想要一个简洁的摘要[没有描述服务/应用程序],可以使用netstat。这里的好处是,不需要sudo权限

netstat -a -n | grep 'LISTEN '

解释所使用的选项

lsof选项(更多详情见man lsof):

  • -n抑制主机名
  • -i适用于IPv4和IPv6协议
  • -P省略端口名称

netstat选项(更多详情见man netstat):

  • -a所有套接字
  • -n不解析名称,以数字显示网络地址

已在 High Sierra 10.13.3 和 Mojave 10.14.3 上进行测试

最后一个语法 netstat 在 Linux 上也有效 [apt 安装 net-tools]

lsof 在某些 Linux 分发版中默认存在


详细的解释对像我这样的初学者非常有用。谢谢@PYK - Tomaz Wang

56
在 macOS 上,您可以使用 netstat 的 -v 选项来查看关联的进程 ID。
输入:
netstat -anv | grep [.]PORT

输出结果将看起来像这样:

tcp46      0      0  *.8080                 *.*                    LISTEN      131072 131072   3105      0

PID是最后一列之前的数字,在本例中为3105。


你还需要添加 grep LISTEN 以仅显示监听者。 - pts
3
这正是我需要的!lsof 找不到这个端口,但 netstat 显示它是开放的。 -v 是我所缺少的关键信息。 - Aaron McMillin

41

在 macOS 上,使用 netstat 可以轻松获取监听特定端口的进程 ID。以下示例查找在端口 80 上提供内容的进程:

查找运行在端口 80 上的服务器

netstat -anv | egrep -w [.]80.*LISTEN

样例输出

tcp4  0 0  *.80       *.*    LISTEN      131072 131072    715      0

倒数第二列是PID,上面的例子中为715

选项

-a - 显示所有端口,包括服务器使用的端口

-n - 显示端口号,不要查找名称。这使得命令运行

-v - 输出详细信息,以获取进程ID

-w - 搜索词语。否则,该命令将返回8000和8001端口的信息,而不仅仅是“80”端口的信息

LISTEN - 仅提供处于LISTEN模式下的端口(即服务器)的信息


2
-v 标志使其成为可能。 - user9869932

22

在最新的macOS版本中,您可以使用这个命令:

lsof -nP -i4TCP:$PORT | grep LISTEN
如果你觉得难以记忆,也许你应该创建一个 bash 函数并将其导出为更友好的名称, 就像这样:
vi ~/.bash_profile

然后将以下行添加到该文件中并保存。

function listening_on() {
    lsof -nP -i4TCP:"$1" | grep LISTEN
}

现在你可以在终端中键入 listening_on 80 并查看哪个进程正在监听端口 80


15

在Snow Leopard(OS X 10.6.8)上运行“man lsof”会产生以下结果:

lsof -i 4 -a

(实际手动输入是'lsof -i 4 -a -p 1234')

之前的回答在Snow Leopard上不起作用,但我一直在尝试使用'netstat -nlp',直到看到pts的回答中使用了'lsof'。


13

我想分享这个命令,它可以很好地工作并打印标题,以便您知道哪一列是哪一个:

lsof -iTCP:8080 -sTCP:LISTEN -P -n

示例输出: {{link1:在此输入图像描述}}


这非常有用!谢谢你。 - foxbit

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