Por que 'kill -9' é matar o navegador e o servidor?

3

Eu às vezes tenho que usar kill -9 como último recurso para matar meu servidor rails. Infelizmente, tenho que fazer isso com a frequência suficiente para que eu escreva uma função auxiliar no meu bash_profile para fazer isso.

Se eu fizer isso manualmente - ps aux | grep '[r]ails] , pegue o pid (por exemplo, 12345 ) e kill -9 12345 - ele mata o servidor e deixa o navegador intacto. Mas minha função também mata o navegador, o que não quero fazer:

function running {
  ps -p $(lsof -i :3000 -t) &> /dev/null
}

function k9 {
  if running
  then
    kill -9 $(lsof -i :3000 -t)
  else
    echo "Rails server is not running"
  fi
}

Confirmei que lsof -i :3000 -t pega o mesmo pid que eu recebo de ps aux , então o que estou fazendo errado?

    
por ivan 09.08.2014 / 23:24

1 resposta

16

O problema:

Com lsof -i :3000 -t , você procurará por qualquer processo conectado a uma porta 3000, que pode estar no lado remoto .

Nos casos em que você usa seu script, o navegador parece ter um connetction para o servidor rails na porta 3000. A diferença está no tempo entre o uso do navegador e o uso de kill .

Isso significa que o navegador também está listado na saída de lsof e foi eliminado.

Você deve matar melhor os processos que se parecem com o seu servidor rails, e não qualquer coisa que esteja usando uma porta 3000, localmente ou em outro lugar.


A solução geral:

pkill é a ferramenta certa para o trabalho.
Para tentar o que é correspondido, use pgrep , que corresponde da mesma maneira:

Se a linha de comando do servidor, conforme mostrado em ps, começar com um nome do comando que identifica sua instância do servidor, você poderá usar pkill servercommand .
Se você precisar corresponder uma parte dos argumentos da linha de comando , adicione -f , como pkill -f serverargument .

Os processos que são mortos por pkill serão listados apenas por pgrep - use isso para tentar o que será morto. Adicione a opção -a a pgrep para listar a linha de comando, em vez do pid apenas.


Exemplos para pgrep / pkill:

Como exemplo de uso de -f : de acordo com ps , essas duas instâncias de xbindkeys estão em execução:

$ ps aux|grep '[x]bindkeys'
26719 ?        S      0:00 xbindkeys -f /tmp/xbindkeysrc-tmp
32046 ?        S      0:00 xbindkeys -f /home/auser/.xbindkeysrc

Agora posso encontrar as duas instâncias com:

$ pgrep xbindkeys
26719
32046

Ou mostrando os comandos:

$ pgrep -a xbindkeys
26719 xbindkeys -f /tmp/xbindkeysrc-tmp
32046 xbindkeys -f /home/auser/.xbindkeysrc

Ou combine uma das instâncias pelos argumentos da linha de comando:

$ pgrep -f '/home/auser/.xbindkeysrc'
32046

Sem -f , nenhum dos processos é correspondido:

$ pgrep '/home/auser/.xbindkeysrc'

Finalmente, enviando o processo um sinal, como com kill :

$ pkill -f '/home/auser/.xbindkeysrc'


Solução alternativa baseada na abordagem original:

A solução com pkill é muito mais geral, mas para seguir sua abordagem original, o comando lsof pode ser mais rigoroso para corresponder ao "qualquer servidor local escutando na porta",
em vez de
"qualquer programa usando a porta local de qualquer forma, ou usando uma porta remota desse número de qualquer forma".

A opção -sTCP:LISTEN restringe a lista às portas que estão ouvindo e, como somente as portas locais podem ser ouvidas, também apenas para portas locais.

Pode ser usado como um teste if como este:

if lsof -i :3000 -sTCP:LISTEN -t >/dev/null ; then
    echo running
else
    echo not running
fi


Nota lateral sobre o uso de SIGKILL, como em kill -9:

O sinal KILL pode ser usado com pkill da mesma maneira que com kill :

$ pkill -9 -f '/home/auser/.xbindkeysrc'

Mas na maioria dos casos gerais, isso não tem vantagem acima do sinal padrão -15 e, em alguns casos, quebra as coisas. Então não é uma boa ideia tornar isso um hábito.

Dê uma olhada em Quando não devo matar -9 um processo? para entender por que você não quer usar -9 por padrão.

    
por 09.08.2014 / 23:51