Como escrever um shscript para matar -9 um pid que é encontrado via lsof -i

29

Estou usando o tomcat e, às vezes, quando digo para parar, não mata o processo corretamente.

Minha maneira de contornar isso também é fazer:

lsof -i tcp:8080

quais saídas:

COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    888 root   35u  IPv6 780659      0t0  TCP *:http-alt (LISTEN)
java    888 root   39r  IPv6 790103      0t0  TCP localhost:58916->localhost:http-alt (CLOSE_WAIT)
java    888 root   40r  IPv6 792585      0t0  TCP localhost:58936->localhost:http-alt (CLOSE_WAIT)
java    888 root   75r  IPv6 785553      0t0  TCP localhost:58701->localhost:http-alt (CLOSE_WAIT)
java    888 root   77r  IPv6 787642      0t0  TCP localhost:58814->localhost:http-alt (CLOSE_WAIT)
java    888 root  130u  IPv6 783894      0t0  TCP localhost:58686->localhost:http-alt (CLOSE_WAIT)
java    888 root  353u  IPv6 780929      0t0  TCP localhost:58632->localhost:http-alt (CLOSE_WAIT)

Então eu corro

kill -9 pid

Eu quero uma maneira de obter todos os números pid e matá-los. O problema é que não sei como isolar esse campo.

user2757729
fonte
1
Se você tem certeza que você só tem uma tomcataberto processo, você pode usarkillall -9 tomcat
Joseph R.

Respostas:

57

Existe uma -topção (concisa) em lsof, que parece fazer exatamente o que você está procurando, ou seja

$ sudo lsof -ti tcp:80
1387
4538
4539

Vejo man lsof

-t       specifies  that  lsof should produce terse output with process
         identifiers only and no header - e.g., so that the output  may
         be piped to kill(1).  -t selects the -w option.

Supondo que você tenha as permissões necessárias, você pode passar o resultado para killuma lista de PIDs com substituição de comando:

kill -9 $(lsof -ti tcp:80)
chave de aço
fonte
Você já respondeu às duas perguntas que fiz;
user2757729
3

Não se esqueça da --no-run-if-emptyopção de matar :)

lsof -ti :8080 | xargs --no-run-if-empty kill -9

Dessa forma, o kill só será executado, há um processo de escuta, não é necessário fazer a verificação você mesmo.

SMF
fonte
'--no-run-if-empty' não é suportado no BSD (mac)
dinesh ygv
1

lsof -i tcp:8080produz a saída, depois | egrep -v "COMMAND PID USER"solta a linha do cabeçalho, depois | awk '{print $2}'imprime o 2º campo, | sort -nprepara os números | uniq, que emitem apenas cada PID único uma vez. Juntar tudo dá:

 lsof -i tcp:8080 | egrep -v "COMMAND PID USER" | awk '{print $2}' | sort -n | uniq  

Mas, pkill -KILL tomcatou killall -KILL tomcaté mais fácil.

waltinator
fonte
O processo do Tomcat não é chamado de "tomcat". Esse é o problema. É apenas um processo java normal, um trabalho extra deve ser feito para identificar o processo correto, se houver outros processos java em execução ao mesmo tempo.
Terry Wang
@TerryWang Yup, esse é o problema que tive também. A resposta da Steeldrivers está funcionando muito bem.
user2757729
0

O único liner da @waltinator é ótimo.

Vou adicionar um pouco mais de sabor a ele:

lsof -i tcp:8080 | egrep -v "COMMAND PID USER" | awk '{print $2}' | sort -n | uniq | xargs kill -9

OU

kill -9 $(lsof -i tcp:8080 | egrep -v "COMMAND PID USER" | awk '{print $2}' | sort -n | uniq)

NOTA: isso ainda é muito básico; talvez seja necessário adicionar mais sal e pimenta para torná-lo mais robusto em um ambiente real.

Terry Wang
fonte
0

Este é o script que eu vim com um pouco de verificação de erro.

#!/bin/bash

PORT=$1

if ! [[ "$PORT" =~ ^[0-9]+$ ]] ;
then
  printf "error: '$PORT' is not a number.\n\nUsage killport <port number>\n"
  exit 1
fi

PID=$(lsof -ti:$PORT)

if ! [[ "$PID" =~ ^[0-9]+$ ]] ;
then
  printf "no proccess found, nothing to kill.\n"
  exit 0
fi

printf "killing process $PID running on $PORT\n"
kill -9 $PID
Loran
fonte
0

Aqui está uma função simples de casca de peixe

function kill-port
  set pids (lsof -ti tcp:$argv)
  if test $pids
    kill -9 $pids
  else
    echo "No proccesses on that port to kill to see for your self -- lsof -i tcp:$argv"
  end
end

basta colocar este otário em um arquivo neste local ~/.config/fish/functions/kill-port.fishe pronto. Você pode chamá-lo comokill-port 8000

codenamejames
fonte