¿Comando Oneliner para usar kill dado el número de puerto tcp en lugar de PID?

8

A menudo hago, por ejemplo

sudo netstat -lpn |grep :8088

ver la salida

tcp6       0      0 :::8088                 :::*                    LISTEN      11189/java

y entonces

sudo kill -kill 11189

Me gustaría tener un comando más conveniente exactamente como killatport 8088ese que usa el número de puerto tcp como variable y que puedo hacer como un alias para una tubería que hace lo que quiero, pero ¿cómo obtengo el PID de la salida y la tubería? a la orden de matar? Supongo que podría usar awk para obtener el PID de la salida de netstat, pero ¿cómo protejo y hago una coincidencia de puerto exacta para que la entrada 80 no coincida con 8080 y lo mismo? ¿Debería convertirlo en un programa C? ¿O ya hay una pequeña utilidad como esta?

Niklas
fuente
1
Usar SIGKILL suele ser una mala idea . ¿Alguna razón por la que no quieres que el proceso se limpie solo?
geirha
Detener el servidor como mvn jetty:stoppodría fallar si la instancia tiene OutOfMemoryError. Cuando reinicio los servlets de Java, sucede que el puerto no está disponible incluso en una parada regular como mvn jetty:stop. A veces, el proceso puede obtener OutOfMemoryErrory no liberará el puerto TCP en un apagado regular como mvn jetty:stop.
Niklas
1
Aún así, mvn jetty:stopno es lo mismo que enviar SIGTERM, y la jvm aún debería poder procesar SIGTERM a pesar de que sus aplicaciones estén fuera de memoria.
geirha

Respuestas:

10

El fusor puede hacer eso:

sudo fuser -KILL -k -n tcp 8088
Florian Diesch
fuente
2

Un comando puede formularse así:

netstat -lpn | grep ":1234\b" | awk '{sub(/\/.*/, "", $NF); print $NF}' | xargs -i kill -kill {}

Explicación:

  1. netstat -ltpn

    • Esto enumera los puertos de escucha ( l) en TCP ( t) y sus programas ( p) sin resolver los números de puerto a los nombres ( n).
  2. grep ":1234\b"

    • Esto busca :1234seguido de un límite ( \b), que indica el final de la palabra (o número, en nuestro caso). Esto asegura que no atrapemos, :12345por ejemplo.
  3. awk '{sub(/\/.*/, "", $NF); print $NF}'

    • Esta

      • sustitutos sub(/regex/,"replacewith", #fieldnumber)
      • esta expresión regular \/.*
      • sin nada ""
      • en el campo $NF, que significa el último campo (es decir, el campo que contiene PID/program)
      • Luego lo imprime print $NF.

      La expresión regular \/.*coincide con un literal /y todo lo que está después, y luego lo reemplazamos por nada, esencialmente lo eliminamos, por lo que solo nos queda el número PID en ese campo.

  4. xargs -i kill -kill {}

    • xargs -ies un programa que le permite hacer que la salida del comando anterior actúe como la entrada a otro comando. Nuestro comando es kill -kill {}donde {}indica "la salida del comando anterior en la tubería", que es nuestro número PID.

Nota: todo este comando puede ser un poco peligroso porque podría matar accidentalmente algo que no quería. Se podría usar con un poco más de desinfección. Solo asegúrese de obtener el número de puerto correcto cuando lo use.

Si desea convertir esto en una función, puede agregar lo siguiente a su ~/.bashrc:

killatport(){
    netstat -lpn | grep ":$1\b" | awk '{sub(/\/.*/, "", $NF); print $NF}' | xargs -i kill -kill {}
}

Guarde y aplique los cambios usando source ~/.bashrc. Ahora, puede usar la función de esta manera:

killatport 8088
Alaa Ali
fuente