У вас сервер отказывается запускаться, потому что на порту 8080 уже что-то работает, и вам нужно найти, что именно его занимает, и завершить этот процесс без перезагрузки всей машины. Такое постоянно происходит в реальной работе системного администратора. Вы перезапускаете службу, получаете сообщение «Адрес уже используется», и теперь вы просматриваете списки процессов, пытаясь выяснить, что же занимает ваш порт.
Решение проблемы довольно простое, если вы знаете нужные команды, и есть три надежных способа это сделать в зависимости от того, какие инструменты доступны в вашей системе.
Сначала найдите, что запущено на порту
Прежде чем что-либо завершать, вам нужно узнать, какой процесс владеет портом. Угадывать и завершать случайные процессы — это верный способ сломать что-нибудь в производственной среде. Поэтому сначала запустите одну из этих команд.
lsof — самый распространенный инструмент для этой цели, и он доступен по умолчанию почти в каждой системе Linux.
sudo lsof -i :8080
Здесь sudo запускает команду с правами root, чтобы lsof можно было увидеть процессы, принадлежащие другим пользователям, а не только вашим собственным. Без этого вы увидите только процессы, запущенные вашим текущим пользователем, а это, как правило, не то, что вам нужно.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 3821 ravi 22u IPv6 54312 0t0 TCP *:8080 (LISTEN)
Этот вывод говорит вам обо всем. node — это имя процесса, 3821 — PID, который вы будете использовать для его завершения, а LISTEN подтверждает, что он активно держит порт открытым. Если вместо этого вы видите ESTABLISHED, то у процесса есть активное соединение через этот порт.
Если lsof не установлен, используйте команду ss, которая входит в пакет iproute2 и доступна практически в любой современной системе Linux.
sudo ss -tulnp | grep :8080
Вот что делает каждый флаг:
-t– показать сокеты TCP-u– показать сокеты UDP-l– показать только сокеты в режиме прослушивания-n– показать номера портов вместо имен служб-p– показать процесс, использующий сокет
tcp LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("node",pid=3821,fd=22))
pid=3821 в конце — это то, что вам нужно. Тот же процесс, тот же PID, просто другой инструмент для его поиска.
Убейте его с помощью команды kill
Как только у вас есть PID, команда kill — это прямой подход. По умолчанию она посылает SIGTERM (сигнал 15), который просит процесс корректно завершить работу и очистить все открытые файловые дескрипторы или соединения перед выходом.
kill 3821
Отсутствие вывода означает, что все сработало. Запустите lsof -i :8080 еще раз, чтобы убедиться.
lsof -i :8080
Если процесс игнорирует SIGTERM и порт по-прежнему занят через несколько секунд, принудите его с помощью SIGKILL (сигнал 9), который немедленно завершает процесс, не давая ему возможности очистить память.
kill -9 3821
Предупреждение: SIGKILL не может быть перехвачен или заблокирован процессом, поэтому он работает всегда, но это также означает, что у процесса нет возможности записать ожидающие данные на диск или корректно закрыть соединения с базой данных. Используйте его в крайнем случае, а не в первую очередь.
Убить напрямую с помощью fuser
Команда fuser полностью обходит двухэтапный подход. Вы указываете номер порта, и она убивает все, что его использует, без необходимости поиска PID.
sudo fuser -k 8080/tcp
-k– отправляет SIGTERM каждому процессу, использующему этот порт.8080/tcp– порт и протокол, на которые вы нацеливаетесь.
8080/tcp: 3821
fuser</code> выводит PID убитого процесса и завершает работу. Вот и всё. Если вы хотите SIGKILL вместо SIGTERM, добавьте <code>-9
sudo fuser -k -9 8080/tcp
Примечание: fuser может быть не установлен по умолчанию на минимальных серверных установках, поэтому установите его, как показано.
sudo apt install psmisc [On Debian, Ubuntu and Mint] sudo dnf install psmisc [On RHEL/CentOS/Fedora and Rocky/AlmaLinux]
Убейте процесс одной строкой, используя lsof и kill вместе
Если вы хотите пропустить ручной поиск PID и убить процесс одной командой, объедините lsof и kill с помощью подстановки команд.
sudo kill -9 $(sudo lsof -t -i :8080)
Вот что делает каждая часть:
lsof -t -i :8080флаг-tвыводит только PID, ничего больше, так что вы получаете чистый номер для передачи в kill$(...)– подстановка команд, запускает внутреннюю команду и передает её вывод в качестве аргумента.kill -9— отправляет SIGKILL любому PID, возвращаемому lsof.
Если после запуска этого порта он возвращается пустым, процесс исчез и порт свободен. Если вы получаете kill: usage или синтаксическую ошибку, порт уже был свободен и lsof ничего не вернул, поэтому kill не с чем было работать.
Совет: Если один и тот же порт используют несколько процессов (редко, но бывает с SO_REUSEPORT), эта однострочная команда убивает их все сразу, поскольку lsof -t может возвращать несколько PID в отдельных строках.
Заключение
Теперь у вас есть 3 рабочих подхода: lsof или ss для определения PID, kill для его завершения с помощью PID, fuser для завершения непосредственно по порту и однострочная команда lsof + kill для тех случаев, когда вы хотите сделать это одной командой.
Единственное, что стоит попробовать прямо сейчас: запустите любой сервис на порту 8080 (python3 -m http.server 8080 подойдет, если у вас установлен Python), затем запустите sudo lsof -i :8080, запишите PID и завершите процесс. Повторите это несколько раз, и навык закрепится быстрее, чем любая закладка.
Комментарии (2)