Komenda Oneliner, aby użyć zabicia podanego numeru portu TCP zamiast PID?

8

Często robię np

sudo netstat -lpn |grep :8088

wyświetl wynik

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

i wtedy

sudo kill -kill 11189

Chciałbym mieć wygodniejszą komendę dokładnie taką, killatport 8088która używa numeru portu TCP jako zmiennej i którą mogę utworzyć jako alias dla potoku, który robi to, co chcę, ale jak uzyskać PID z wyjścia i potoku to do polecenia zabicia? Przypuszczam, że mógłbym użyć awk, aby uzyskać PID z wyjścia z netstat, ale jak mogę zabezpieczyć i dopasować dokładny port, aby wejście 80 nie pasowało do 8080 i podobnie? Czy powinienem zamiast tego zrobić program w języku C? A może istnieje już takie małe narzędzie?

Niklas
źródło
1
Korzystanie z SIGKILL jest zwykle złym pomysłem . Jest jakiś powód, dla którego nie chcesz, aby proces sam się wyczyścił?
geirha
Zatrzymanie serwera, ponieważ mvn jetty:stopmoże to zakończyć się niepowodzeniem, jeśli instancja ma OutOfMemoryError. Kiedy ponownie uruchamiam serwlety Java, zdarza się, że port jest niedostępny, nawet przy regularnym zatrzymaniu, takim jak mvn jetty:stop. Czasami proces może uzyskać OutOfMemoryErrori nie zwolnić portu TCP przy regularnym wyłączaniu, takim jak mvn jetty:stop.
Niklas
1
Nadal mvn jetty:stopnie jest tym samym, co wysyłanie SIGTERM, a jvm nadal powinien móc przetwarzać SIGTERM, nawet jeśli w jego aplikacjach brakuje pamięci.
geirha

Odpowiedzi:

2

Polecenie można sformułować w następujący sposób:

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

Wyjaśnienie:

  1. netstat -ltpn

    • Wyświetla listę nasłuchujących portów ( l) w TCP ( t) i ich programach ( p) bez rozdzielania numerów portów na names ( n).
  2. grep ":1234\b"

    • Wyszukuje :1234po nim granicę ( \b), wskazującą koniec słowa (lub w naszym przypadku cyfry). To :12345gwarantuje , że nie złapiemy na przykład.
  3. awk '{sub(/\/.*/, "", $NF); print $NF}'

    • To

      • zamienniki sub(/regex/,"replacewith", #fieldnumber)
      • to wyrażenie regularne \/.*
      • z niczym ""
      • w polu $NF, co oznacza ostatnie pole (tj. pole zawierające PID/program)
      • następnie drukuje print $NF.

      Wyrażenie regularne \/.*dopasowuje literał /i wszystko po nim, a następnie zastępujemy go niczym, zasadniczo usuwając go, więc pozostaje nam tylko numer PID w tym polu.

  4. xargs -i kill -kill {}

    • xargs -ito program, który pozwala, aby dane wyjściowe z poprzedniego polecenia działały jako dane wejściowe do innego polecenia. Nasze polecenie to kill -kill {}gdzie {}wskazuje „wynik z poprzedniego polecenia w potoku”, który jest naszym numerem PID.

Uwaga: całe to polecenie może być trochę niebezpieczne, ponieważ możesz przypadkowo zabić coś, czego nie chcesz. Przydałoby się to z nieco większą dezynfekcją. Po prostu upewnij się, że otrzymujesz poprawny numer portu podczas jego używania.

Jeśli chcesz zrobić z tego funkcję, możesz dodać do swojego ~/.bashrc:

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

Zapisz i zastosuj zmiany za pomocą source ~/.bashrc. Teraz możesz użyć takiej funkcji:

killatport 8088
Alaa Ali
źródło