Home

Listing the ports in use on Linux

How do you tell which ports are in use on a Linux or Unix-like server? It comes up all the time — debugging which app is squatting on a port, sanity-checking that nothing unexpected is listening, or just confirming you can put Nginx on 80 without hitting an existing Apache. The two tools I reach for are lsof and ss (or its older sibling netstat).

1. lsof

bash
lsof -i -P -nlsof -i -P -n | grep LISTEN  # only listening sockets

Sample output:

bash
 lsof -i -P -n | grep LISTENsystemd-r   549 systemd-resolve   13u  IPv4   20972      0t0  TCP 127.0.0.53:53 (LISTEN)nginx       739            root   11u  IPv4   24520      0t0  TCP *:80 (LISTEN)nginx       739            root   12u  IPv6   24521      0t0  TCP *:80 (LISTEN)nginx       739            root   13u  IPv4   24522      0t0  TCP *:22222 (LISTEN)nginx       739            root   14u  IPv4   24523      0t0  TCP *:443 (LISTEN)nginx       739            root   15u  IPv6   24524      0t0  TCP *:443 (LISTEN)sshd       1065            root    3u  IPv4 1215778      0t0  TCP *:22 (LISTEN)sshd       1065            root    4u  IPv6 1215780      0t0  TCP *:22 (LISTEN)netdata    1122         netdata    5u  IPv4   28641      0t0  TCP *:19999 (LISTEN)mariadbd  23070           mysql   24u  IPv6 1217922      0t0  TCP 127.0.0.1:3306 (LISTEN)php-fpm7. 59769            root    7u  IPv4  808985      0t0  TCP 127.0.0.1:9174 (LISTEN)

Each line tells you the binary, the PID, the user, the protocol, and the address it's bound to. Reading one row:

bash
COMMAND   PID    USER       FD   TYPE DEVICE                        ADDRESSmariadbd  23070  mysql      24u  IPv6 1217922      0t0  TCP 127.0.0.1:3306 (LISTEN)

So MariaDB is listening on 127.0.0.1:3306 as the mysql user with PID 23070.

2. ss (or netstat)

netstat is deprecated on modern kernels — ss from iproute2 is the replacement and is faster on busy hosts.

bash
ss -tulwnss -tulwn | grep LISTEN  # only listening sockets

If you're on an older box, netstat still works:

bash
netstat -tulpn | grep LISTEN

Sample ss output:

bash
 ss -tulp | grep LISTENtcp   LISTEN 0      511                         0.0.0.0:22222       0.0.0.0:*    users:(("nginx",pid=742,fd=13))tcp   LISTEN 0      511                         0.0.0.0:http        0.0.0.0:*    users:(("nginx",pid=742,fd=11))tcp   LISTEN 0      4096                  127.0.0.53%lo:domain      0.0.0.0:*    users:(("systemd-resolve",pid=549,fd=13))tcp   LISTEN 0      32768                     127.0.0.1:9174        0.0.0.0:*    users:(("php-fpm7.4",pid=59769,fd=7))tcp   LISTEN 0      511                         0.0.0.0:https       0.0.0.0:*    users:(("nginx",pid=742,fd=14))tcp   LISTEN 0      128                         0.0.0.0:22          0.0.0.0:*    users:(("sshd",pid=1065,fd=3))tcp   LISTEN 0      4096                        0.0.0.0:19999       0.0.0.0:*    users:(("netdata",pid=1122,fd=5))

The flags I use most:

bash
-t  TCP only-u  UDP only-l  listening sockets only-p  show the process name and PID using each socket-n  numeric don't resolve port names or IPs

ss -tulpn is the one-liner that lives in my muscle memory.