Если локальный сервер разработки сообщает, что порт уже занят, используйте встроенную в macOS команду lsof, чтобы найти процесс, прослушивающий этот TCP-порт. В Терминале выполните lsof с указанием номера порта и фильтра состояния прослушивания, а затем используйте полученный PID для проверки процесса, прежде чем принимать решение о его завершении.

Поиск процесса, прослушивающего TCP-порт

Откройте Терминал и замените 3000 на порт из сообщения об ошибке. Введите команду, как показано; номер представляет собой обычный текст, поэтому экранирование в оболочке не требуется.

lsof -nP -iTCP:3000 -sTCP:LISTEN

Команда lsof выводит список файлов, открытых процессами, включая интернет-сокеты. В данном случае параметр -iTCP:3000 выбирает TCP-соединения для этого порта, а -sTCP:LISTEN сужает результаты до сокетов, ожидающих входящих подключений. Параметр -nP указывает lsof отображать числовые адреса и номера портов вместо разрешения имен, благодаря чему результат проще сопоставить с искомым портом. Эти параметры описаны в руководстве по lsof с открытым исходным кодом от Apple. Руководство по lsof для macOS от Apple

Результат может выглядеть следующим образом; имена и числа приведены для примера, а не взяты с конкретного Mac:

COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node     8421 sam    21u  IPv6 ...          0t0    TCP *:3000 (LISTEN)

В поле COMMAND указано имя процесса, а в PID — его идентификатор процесса. В поле NAME отображаются локальный адрес и порт. Значение *:3000 обозначает подстановочный адрес (wildcard), тогда как localhost:3000 или числовой loopback-адрес указывает на привязку к локальному интерфейсу (loopback). Прослушиватель с подстановочным адресом может принимать соединения, направленные на несколько локальных интерфейсов; само по себе это не означает, что служба доступна из интернета. Фильтр прослушивания полезен тем, что у процесса также могут быть обычные клиентские соединения, использующие тот же самый порт.

Проверка принадлежности PID

Используйте PID из полученного вывода, чтобы запросить более подробную информацию из списка процессов macOS. Замените 8421 на найденный вами PID:

ps -p 8421 -o pid=,ppid=,user=,command=

Эта команда выведет идентификатор процесса, идентификатор родительского процесса, имя учетной записи и командную строку. Командная строка помогает определить, принадлежит ли прослушиватель серверу разработки, среде выполнения или другому приложению. Короткого значения COMMAND в выводе lsof не всегда достаточно для идентификации проекта или запустившей его программы, поэтому сопоставьте более полный вывод ps с вкладкой Терминала или приложением, которое, как вы предполагаете, запустило сервер.

Если lsof ничего не возвращает, убедитесь, что номер порта указан верно и приложение все еще работает. Сервер мог завершить работу, использовать протокол UDP вместо TCP или еще не успеть открыть прослушивающий сокет. Чтобы проверить UDP-сокеты на этом порту, выполните:

lsof -nP -iUDP:3000

Протокол UDP не использует состояние TCP LISTEN, поэтому не добавляйте -sTCP:LISTEN к этому запросу. Если результат появится, используйте параметры COMMAND и PID как подсказки, а затем проверьте этот PID с помощью ps, как описано выше.

Если команда не дает результатов или возникает ошибка доступа

Процесс, запущенный от имени другой учетной записи, может быть невидим для вашего текущего пользователя. Если вы получаете сообщение об ошибке доступа или подозреваете, что сокет принадлежит другому пользователю, выполните запрос TCP повторно с правами администратора:

sudo lsof -nP -iTCP:3000 -sTCP:LISTEN

Терминал запросит пароль вашей учетной записи Mac. При вводе символы обычно не отображаются; по завершении нажмите Return. Используйте права администратора для просмотра результата, а затем определите приложение-владелец, прежде чем предпринимать какие-либо действия. Если команда по-прежнему ничего не показывает, повторите попытку в тот момент, когда происходит конфликт портов: состояние процесса может измениться в промежутке между возникновением ошибки и выполнением поиска.

Завершение нужного приложения

Обнаружение PID определяет процесс; оно не говорит о том, безопасно ли его завершать. Если вы знаете владельца, остановите сервер с помощью приложения или сеанса Терминала, в котором он был запущен, а затем повторите исходную команду. Это даст приложению возможность завершить работу в штатном режиме. Если вы не можете определить, что запустило процесс, сначала изучите командную строку или родительский PID, вместо того чтобы завершать незнакомый системный или фоновый процесс. Утилита lsof сообщает о текущем владельце сокета; она не объясняет, почему приложение было запущено или какая конфигурация проекта выбрала этот порт.

Для получения подробных сведений о команде в установленной версии macOS Терминал может отобразить локальное руководство с помощью команды man lsof; для выхода нажмите q. В руководстве Apple по Терминалу описано использование man для поиска документации по командам. Начало работы с Терминалом на Mac

Источники