Во время разработки периодически возникают ситуации, когда вы запустили,

например, 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 утилиты, которые помогут найти и убить процесс,

который занял порт. Надеюсь, эта информация окажется вам полезной и спасет вас

от лишних затрат времени на поиски решения в будущем.