Linux中是誰占用了我的端口
Address already in use這個提示,想必大家遇到過,怎么能快速找到問題并解決呢?下面有幾種姿勢可以了解一下.
在對網(wǎng)絡連接或特定于應用程序的問題進行故障排除時,首先要檢查的事情之一應該是系統(tǒng)上實際使用了哪些端口,以及哪個應用程序正在偵聽特定的端口。
本文介紹了如何使用netstat,ss和lsof命令找出哪些服務正在偵聽哪些端口。該說明適用于所有基于Linux和Unix的操作系統(tǒng),例如macOS。
# 什么是監(jiān)聽端口
網(wǎng)絡端口由其編號,關聯(lián)的IP地址和通信協(xié)議(例如TCP或UDP)的類型標識。
偵聽端口是應用程序或進程在其上偵聽的網(wǎng)絡端口,充當通信端點。
每個監(jiān)聽端口都可以使用防火墻打開或關閉(過濾)。一般而言,開放端口是一個網(wǎng)絡端口,它接受來自遠程位置的傳入數(shù)據(jù)包。
你不能讓兩個服務監(jiān)聽同一IP地址上的同一端口。
例如,如果你正在運行一個監(jiān)聽端口80和443的Apache Web服務器,并且嘗試安裝Nginx ,則后者將無法啟動,因為HTTP和HTTPS端口是已經(jīng)在使用中。
# 用netstat檢查監(jiān)聽端口
netstat是一個命令行工具,可以提供有關網(wǎng)絡連接的信息。
要列出所有正在偵聽的TCP或UDP端口,包括使用端口的服務和套接字狀態(tài),請使用以下命令:
- sudo netstat -tunlp
此命令中使用的選項具有以下含義:
- -t-顯示TCP端口。
- -u -顯示UDP端口。
- -n -顯示數(shù)字地址而不是解析主機。
- -l -僅顯示監(jiān)聽端口。
- -p -顯示偵聽器進程的PID和名稱。僅當你以root用戶或 sudo 用戶身份運行命令時,才會顯示此信息。
輸出將如下所示:
- Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
- tcp 0 0 0:22 0:* LISTEN 445/sshd
- tcp 0 0 0:25 0:* LISTEN 929/master
- tcp6 0 0 :::3306 ::* LISTEN 534/mysqld
- tcp6 0 0 :::80 :::* LISTEN 515/apache2
- tcp6 0 0 :::22 :::* LISTEN 445/sshd
- tcp6 0 0 :::25 :::* LISTEN 929/master
- tcp6 0 0 :::33060 :::* LISTEN 534/mysqld
- udp 0 0 0:68 0:* 966/dhclient
在我們的案例中,重要的幾列是:
- Proto-套接字使用的協(xié)議。
- Local Address -進程偵聽的IP地址和端口號。
- PID/Program name -PID和進程名稱。
如果要過濾結果,請使用 grep命令。例如,要查找在TCP端口22上偵聽的進程,你可以輸入:
- sudo netstat -tnlp | grep :22
輸出顯示此計算機上的端口22被SSH服務器使用:
- tcp 0 0 0:22 0:* LISTEN 445/sshd
- tcp6 0 0 :::22 :::* LISTEN 445/sshd
如果輸出為空,則表示端口上沒有監(jiān)聽。
你也可以根據(jù)條件過濾列表,例如PID,協(xié)議,狀態(tài)等。
netstat已過時,被ss和 ip 取代,但它仍然是檢查網(wǎng)絡連接的最常用命令。
# 用ss
檢查監(jiān)聽端口
ss是新的netstat。它缺少netstat的某些功能,但是公開了更多的TCP狀態(tài),并且速度稍快。命令選項基本相同,因此從netstat到ss的轉(zhuǎn)換并不困難。
要使用ss獲取所有監(jiān)聽端口的列表,請輸入:
- sudo ss -tunlp
輸出與netstat報告的輸出幾乎相同:
- State Recv-Q Send-Q Local Address:Port Peer Address:Port
- LISTEN 0 128 0:22 0:* users:(("sshd",pid=445,fd=3))
- LISTEN 0 100 0:25 0:* users:(("master",pid=929,fd=13))
- LISTEN 0 128 *:3306 *:* users:(("mysqld",pid=534,fd=30))
- LISTEN 0 128 *:80 *:* users:(("apache2",pid=765,fd=4),("apache2",pid=764,fd=4),("apache2",pid=515,fd=4))
- LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=445,fd=4))
- LISTEN 0 100 [::]:25 [::]:* users:(("master",pid=929,fd=14))
- LISTEN 0 70 *:33060 *:* users:(("mysqld",pid=534,fd=33))
# 使用lsof
檢查監(jiān)聽端口
lsof是功能強大的命令行應用程序,可提供有關進程打開的文件的信息。
在Linux中,所有內(nèi)容都是文件。你可以將套接字視為寫入網(wǎng)絡的文件。
要獲取具有l(wèi)sof的所有偵聽TCP端口的列表,請輸入:
- sudo lsof -nP -iTCP -sTCP:LISTEN
使用的選項如下:
- -n-不要將端口號轉(zhuǎn)換為端口名稱。
- -p -不解析主機名,顯示數(shù)字地址。
-iTCP -sTCP:LISTEN -僅顯示TCP狀態(tài)為LISTEN的網(wǎng)絡文件。
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- sshd 445 root 3u IPv4 16434 0t0 TCP *:22 (LISTEN)
- sshd 445 root 4u IPv6 16445 0t0 TCP *:22 (LISTEN)
- apache2 515 root 4u IPv6 16590 0t0 TCP *:80 (LISTEN)
- mysqld 534 mysql 30u IPv6 17636 0t0 TCP *:3306 (LISTEN)
- mysqld 534 mysql 33u IPv6 19973 0t0 TCP *:33060 (LISTEN)
- apache2 764 www-data 4u IPv6 16590 0t0 TCP *:80 (LISTEN)
- apache2 765 www-data 4u IPv6 16590 0t0 TCP *:80 (LISTEN)
- master 929 root 13u IPv4 19637 0t0 TCP *:25 (LISTEN)
- master 929 root 14u IPv6 19638 0t0 TCP *:25 (LISTEN)
大多數(shù)輸出列名稱都是不言自明的:
- COMMAND,PID,USER-運行與端口關聯(lián)的程序的名稱,PID和用戶。
- NAME -端口號。
要查找正在偵聽特定端口(例如端口3306)的進程,可以使用:
- sudo lsof -nP -iTCP:3306 -sTCP:LISTEN
輸出顯示MySQL服務器使用端口3306:
- COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
- mysqld 534 mysql 30u IPv6 17636 0t0 TCP *:3306 (LISTEN)