Commande Oneliner pour utiliser le numéro de port TCP donné au lieu du PID?

8

Je fais souvent par exemple

sudo netstat -lpn |grep :8088

voir la sortie

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

et alors

sudo kill -kill 11189

J'aimerais avoir une commande plus pratique exactement comme killatport 8088celle qui utilise le numéro de port tcp comme variable et que je peux créer comme alias pour un pipeline qui fait ce que je veux, mais comment puis-je obtenir le PID de la sortie et du tuyau à la commande kill? Je suppose que je pourrais être en mesure d'utiliser awk pour obtenir le PID de la sortie de netstat, mais comment puis-je sauvegarder et faire une correspondance de port exacte afin que l'entrée 80 ne corresponde pas à 8080 et de même? Dois-je plutôt en faire un programme C? Ou existe-t-il déjà un petit utilitaire comme celui-ci?

Niklas
la source
1
Utiliser SIGKILL est généralement une mauvaise idée . Une raison pour laquelle vous ne voulez pas que le processus se nettoie après lui-même?
geirha
L'arrêt du serveur mvn jetty:stoppourrait échouer si l'instance l'a fait OutOfMemoryError. Lorsque je redémarre les servlets java, il arrive que le port ne soit pas disponible même à un arrêt régulier tel que mvn jetty:stop. Parfois, le processus peut obtenir OutOfMemoryErroret ne libérera pas le port TCP lors d'un arrêt régulier tel que mvn jetty:stop.
Niklas
1
Pourtant, ce mvn jetty:stopn'est pas la même chose que d'envoyer SIGTERM, et le jvm devrait toujours être en mesure de traiter SIGTERM même si sa ou ses applications sont hors mem.
geirha

Réponses:

2

Une commande peut être formulée comme ceci:

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

Explication:

  1. netstat -ltpn

    • Ceci répertorie les ports d'écoute ( l) sur TCP ( t) et leurs programmes ( p) sans résoudre les numéros de port en noms ( n).
  2. grep ":1234\b"

    • Cela recherche :1234suivi par une limite ( \b), indiquant la fin du mot (ou nombre, dans notre cas). Cela garantit que nous n'attrapons pas :12345par exemple.
  3. awk '{sub(/\/.*/, "", $NF); print $NF}'

    • Cette

      • substituts sub(/regex/,"replacewith", #fieldnumber)
      • ce regex \/.*
      • avec rien ""
      • dans le champ $NF, ce qui signifie le dernier champ (c'est-à-dire le champ qui contient PID/program)
      • puis l'imprime print $NF.

      Le regex \/.*correspond à un littéral /et à tout ce qui le suit, puis nous le remplaçons par rien, le supprimant essentiellement, il nous reste donc uniquement le numéro PID dans ce champ.

  4. xargs -i kill -kill {}

    • xargs -iest un programme qui vous permet de faire de la sortie de la commande précédente l'entrée d'une autre commande. Notre commande est kill -kill {}{}indique "la sortie de la commande précédente dans le pipeline", qui est notre numéro PID.

Remarque: toute cette commande peut être un peu dangereuse car vous pourriez accidentellement tuer quelque chose que vous ne vouliez pas. Il pourrait être utilisé avec un peu plus de désinfection. Assurez-vous simplement d'obtenir le bon numéro de port lorsque vous l'utilisez.

Si vous souhaitez en faire une fonction, vous pouvez ajouter ce qui suit à votre ~/.bashrc:

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

Enregistrez et appliquez les modifications à l'aide de source ~/.bashrc. Maintenant, vous pouvez utiliser la fonction comme ceci:

killatport 8088
Alaa Ali
la source