Comando Oneliner para usar kill dado o número da porta TCP em vez do PID?

8

Eu costumo fazer, por exemplo

sudo netstat -lpn |grep :8088

ver a saída

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

e depois

sudo kill -kill 11189

Eu gostaria de ter um comando mais conveniente, exatamente como killatport 8088esse, que use o número da porta tcp como variável e que eu possa criar um alias para um pipeline que faça o que eu quero, mas como obtenho o PID da saída e do pipe ao comando kill? Suponho que posso usar o awk para obter o PID da saída do netstat, mas como faço para proteger e fazer uma correspondência exata de porta para que a entrada 80 não corresponda a 8080 e da mesma forma? Devo torná-lo um programa C? Ou já existe um pequeno utilitário como este?

Niklas
fonte
1
Usar o SIGKILL geralmente é uma má ideia . Alguma razão para você não querer que o processo seja limpo depois de si mesmo?
Geirha
Parar o servidor como mvn jetty:stoppoderia falhar se a instância o tiver OutOfMemoryError. Quando eu reinicio os servlets java, acontece que a porta não está disponível mesmo em uma parada regular, como mvn jetty:stop. Às vezes, o processo pode obter OutOfMemoryErrore não liberará a porta TCP em um desligamento regular, como mvn jetty:stop.
Niklas
1
Ainda assim, mvn jetty:stopnão é o mesmo que enviar o SIGTERM, e a jvm ainda deve poder processar o SIGTERM, mesmo que seus aplicativos estejam sem memória.
Geirha

Respostas:

10

O fusor pode fazer isso:

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

Um comando pode ser formulado assim:

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

Explicação:

  1. netstat -ltpn

    • Isso lista as portas de escuta ( l) no TCP ( t) e seus programas ( p) sem resolver os números de porta nos nomes ( n).
  2. grep ":1234\b"

    • Ele procura :1234seguido por um limite ( \b), indicando o final da palavra (ou número, no nosso caso). Isso garante que não capturamos, :12345por exemplo.
  3. awk '{sub(/\/.*/, "", $NF); print $NF}'

    • este

      • substitutos sub(/regex/,"replacewith", #fieldnumber)
      • este regex \/.*
      • com nada ""
      • no campo $NF, o que significa o último campo (ou seja, o campo que contém PID/program)
      • depois imprime print $NF.

      O regex \/.*corresponde a um literal /e tudo depois dele, e então o substituímos por nada, essencialmente o excluindo; portanto, resta apenas o número PID nesse campo.

  4. xargs -i kill -kill {}

    • xargs -ié um programa que permite que a saída do comando anterior atue como entrada para outro comando. Nosso comando é kill -kill {}onde {}indica "a saída do comando anterior no pipeline", que é o nosso número PID.

Nota: todo esse comando pode ser um pouco perigoso, porque você pode matar acidentalmente algo que não queria. Poderia usar com um pouco mais de higienização. Apenas certifique-se de obter o número da porta correto ao usá-lo.

Se você quiser transformar isso em uma função, adicione o seguinte ao seu ~/.bashrc:

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

Salve e aplique as alterações usando source ~/.bashrc. Agora, você pode usar a função assim:

killatport 8088
Alaa Ali
fonte