Matar un proceso en un puerto en Mac: encuentra el PID y libéralo
Descubre qué proceso usa un puerto en tu Mac y ciérralo con lsof y kill -9, incluidos los servicios de macOS que se reinician solos.
Quieres el puerto 8080 libre. No importa qué lo está usando. Simplemente necesitas que desaparezca. macOS te da las herramientas para hacerlo en un solo comando de Terminal, una vez que conoces las opciones correctas. Si quieres ver el panorama completo de todo lo que tu Mac tiene abierto antes de decidir qué liberar, primero revisa todos los puertos abiertos en tu Mac.
Primero, encuentra el proceso
lsof te dice qué proceso tiene un puerto abierto. La opción -i filtra por socket de red, y :PUERTO lo acota a un número de puerto específico:
lsof -i :8080
Salida de ejemplo:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 4821 aaron 42u IPv6 0x... 0t0 TCP *:http-alt (LISTEN)
La columna PID es lo que necesitas. En este caso es 4821.
Mátalo
kill -9 4821
La opción -9 envía SIGKILL, que obliga al proceso a terminar de inmediato. El proceso no puede capturar ni ignorar esta señal. El sistema operativo lo termina y libera el puerto.
Comando directo: busca y mata en un solo paso
Si solo quieres liberar el puerto sin necesidad de inspeccionar el proceso primero, puedes hacer los dos pasos a la vez:
kill -9 $(lsof -ti :8080)
La opción -t hace que lsof devuelva solo el PID: sin encabezados ni columnas extra. Eso lo hace seguro para sustituirlo directamente en kill.
SIGTERM vs SIGKILL
La opción -9 no siempre es la elección correcta. Hay dos señales habituales:
- SIGTERM (señal 15): le pide al proceso que termine de forma ordenada. El proceso puede capturar esta señal y hacer limpieza (guardar escrituras pendientes, cerrar conexiones de base de datos, guardar el estado) antes de salir. Se usa con
kill 4821sin ninguna opción. - SIGKILL (señal 9): obliga al proceso a terminar de inmediato. Sin limpieza, sin aviso. Se usa con
kill -9 4821.
Para un servidor de desarrollo atascado que bloquea tu puerto, SIGKILL está bien. Para una base de datos o cualquier proceso que esté escribiendo en disco, prueba primero con SIGTERM y dale unos segundos. Si no termina, entonces usa SIGKILL. ¿No sabes qué proceso es antes de matarlo? Primero identifica qué app tiene el puerto.
Cuando el puerto tiene varios procesos
A veces lsof devuelve más de un PID. Esto ocurre cuando un proceso padre bifurca procesos de trabajo que comparten el mismo socket:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1100 root 6u IPv4 ... 0t0 TCP *:80 (LISTEN)
nginx 1101 aaron 6u IPv4 ... 0t0 TCP *:80 (LISTEN)
nginx 1102 aaron 6u IPv4 ... 0t0 TCP *:80 (LISTEN)
Para terminarlos todos a la vez:
kill -9 $(lsof -ti :80)
Como -t devuelve cada PID en su propia línea, el shell los pasa todos a kill como argumentos separados. Los tres procesos se terminan.
Protégete del PID equivocado
Un error tipográfico o un número de puerto incorrecto puede matar el proceso equivocado. Antes de ejecutar un comando kill en un sistema compartido o de producción, confirma que el nombre del proceso en la salida de lsof coincide con lo que esperas.
Si la columna COMMAND muestra algo como postgres, redis-server u otro servidor de base de datos, y tú esperabas un servidor de desarrollo Node.js, para y revisa. Matar una base de datos mientras está escribiendo puede corromper los datos. Los servidores de desarrollo en puertos comunes como puerto 3000 en uso a menudo muestran este patrón cuando bifurcan workers.
Los procesos de macOS que vuelven enseguida
En un Mac, algunos puertos los ocupan servicios del sistema bajo launchd. Matarlos no sirve de nada: launchd los vuelve a lanzar en cuestión de segundos, y en algunos casos pierdes funcionalidad hasta que vuelves a iniciar sesión.
- Puerto 5000 y 7000 (
ControlCenter): el receptor de AirPlay, activado por defecto desde macOS Monterey. Esta es la razón más habitual por la que un servidor de desarrollo de Flask no puede enlazar el puerto 5000 en un Mac. No lo mates. Desactívalo en Ajustes del Sistema, General, AirDrop y Handoff, Receptor de AirPlay, y luego enlaza el puerto con normalidad. - Puerto 5353 (
mDNSResponder): Bonjour. Matarlo interrumpe el descubrimiento de red local, la compartición de impresoras y AirPlay hasta quelaunchdlo reinicia. Siempre vuelve. - Puerto 631 (
cupsd): el sistema de impresión. Se relanza bajo demanda la próxima vez que algo toque una cola de impresión. - Puerto 62078 (
lockdownd): el proceso que escucha la sincronización del iPhone. Aparece cuando se empareja un dispositivo por USB o por sincronización Wi-Fi. - Puerto 17500 (
Dropbox): descubrimiento de sincronización en la red local. Se puede matar sin problema, pero Dropbox lo vuelve a arrancar en el siguiente inicio.
Si lsof muestra uno de estos y esperabas ver tu propio servidor de desarrollo, estás mirando el proceso equivocado. Cambia de puerto o desactiva el servicio en lugar de matarlo.
Por qué a veces kill -9 deja el puerto ocupado
De vez en cuando el proceso ya no existe y el puerto se sigue negando a enlazarse. Dos causas específicas de macOS:
El socket está en TIME_WAIT. Un socket TCP cerrado permanece abierto un rato para que los paquetes que llegan con retraso no acaben en un nuevo proceso en escucha. En macOS esa espera es de unos 30 segundos, no los dos minutos que se suelen citar: la duración equivale al doble del tiempo de vida máximo del segmento (MSL), y macOS trae un MSL de 15 segundos. Linux no calcula el TIME_WAIT a partir de un MSL: fija el tiempo total en 60 segundos de forma directa (TCP_TIMEWAIT_LEN en el kernel). Comprueba el valor de macOS con sysctl net.inet.tcp.msl, que devuelve el resultado en milisegundos. Confirma el estado del socket con:
netstat -an | grep 8080
Si la columna de estado muestra TIME_WAIT, nada está ocupando el puerto y basta con esperar. Un servidor que configura SO_REUSEADDR puede enlazarse directamente sin esperar, por eso la mayoría de los servidores de desarrollo nunca se topan con esto.
Un proceso padre volvió a bifurcar un worker. Matar al hijo libera el puerto por un instante antes de que el padre genere un reemplazo en el mismo socket. Comprueba si existe un proceso padre que sigue vivo:
ps -o pid,ppid,command -p $(lsof -ti :8080)
Si la columna PPID señala a un proceso que no es launchd (PID 1), mata al padre en su lugar. Matar hijos en bucle nunca va a funcionar.
Usando Portie
Portie muestra todos los puertos abiertos de tu Mac en una lista en vivo, actualizada cada 3 segundos. Puedes ver el nombre del proceso y el PID de cada puerto de un vistazo. Sin tener que recordar opciones.
El nivel gratuito incluye el monitoreo local. El desbloqueo por $8.99 de pago único agrega la posibilidad de matar un proceso directamente desde la lista con un solo clic. Eliges SIGTERM o SIGKILL desde un menú. Sin Terminal.