Как на linux найти процесс слушающий порт?
September 29, 2020
Во время разработки периодически возникают ситуации, когда вы запустили,
например, NodeJs сервер и в какой-то момент произошла ошибка. Вы прерываете
процесс через Ctrl+C
, запускаете сервер заново, но в ответ видите ошибку
Error: listen EADDRINUSE: address already in use :::3000
. Самое неприятное с
этой ошибкой то, что вы вроде бы остановили процесс, однако несмотря на это,
процесс так и не освободил порт и все еще крутится где-то в памяти. В этом посте
речь пойдет о том, как отловить такие процессы и все же убить их.
Чтобы убить процесс в linux, вам необходимо использовать команду kill
с
сигналом 9
(SIGKILL):
kill -9 <PID>
Чтобы получить process id (PID), нужно выполнить другую команду. При чем в конкретно нашей ситуации, нам нужно найти процесс по номеру порта, который он занял. Разновидностей команд для решения такой задачи есть доволь но много и далеко не все из этих программ будут установлены в системе, с которой вам придется работать. Потому далее предлагаю несколько альтернативных команд, чтобы было из чего выбирать. Начну с той, которую обычно использую сам.
Обратите внимание, если процесс был запущен на порту
:80
или если он был запущен другим юзером, скорее всего вам понадобится добавитьsudo
, чтобы выполнить команду с правами администратора, иначе со своего юзера вы либо не сможете увидеть процессы, либо не увидите их PID.
lsof
Чтобы проверить какой процесс слушает на порту 3000
, необходимо ввести
следующую команду:
lsof -i :3000
Расшифровку ключей можно посмотреть здесь
В ответ получите нечто на подобии этого:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 241907 sleepwalker 38u IPv6 3609283 0t0 TCP *:3000 (LISTEN)
Можно так же передать флаг -t
, чтобы получить только pid. Это дает возможность
убить нужный процесс в одну строку:
kill -9 $(lsof -t -i:3000)
fuser
fuser -v -n tcp 3000
вывод команды будет выглядеть так:
USER PID ACCESS COMMAND
3000/tcp: sleepwalker 367896 F.... node
Расшифровку ключей можно посмотреть здесь
Более короткий вариант команды:
fuser 3000/tcp
Кроме того, можно сразу попросить fuser
убить процесс:
fuser -k 3000/tcp
ss
ss -tlpn
вывод команды будет выглядеть так:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 127.0.0.1:3000 0.0.0.0:* users:(("node",pid=365730,fd=22))
LISTEN 0 511 127.0.0.1:42679 0.0.0.0:* users:(("code",pid=338363,fd=109))
LISTEN 0 5 127.0.0.1:631 0.0.0.0:*
LISTEN 0 1 0.0.0.0:7070 0.0.0.0:*
Расшифровку ключей можно посмотреть здесь
Самый простой способ сократить вывод команды — использовать
grep
:ss -tlpn | grep 3000
.
netstat
netstat -tlpn
Вот так будет выглядеть вывод команды:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::3000 :::* LISTEN 25/.pm2)
tcp 0 0 :::27017 :::* LISTEN -
Расшифровку ключей можно посмотреть
здесь. Флаг -t
отфильтровывает только TCP соединения.
Самый простой способ сократить вывод команды — использовать
grep
:netstat -tlpn | grep 3000
.
Выводы
В этом посте было рассмотрено 4 утилиты, которые помогут найти и убить процесс, который занял порт. Надеюсь, эта информация окажется вам полезной и спасет вас от лишних затрат времени на поиски решения в будущем.