Eu iniciei um aplicativo que não será executado, mas não posso excluí-lo porque ainda está em execução. Eu posso imprimir o PID, mas não matar o processo usando ele.
~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process
snappr
estivesse rodando, o primeiro comando teria listado dois PIDs: o dosnappr
e o dogrep
- como explicado na minha resposta, que eu postei meia hora antes de você postar este comentário. ... ... ... ... ... PS Você pode querer revisar suas contribuições um pouco melhor ("Eu afirmo o erro", "ad", "mit").grep snappr
está combinando o processogrep snappr
.Respostas:
Você percebeu que você tem dois PIDs diferentes nas duas tentativas?
Considere isto: se você digitar um comando como
vi raven.txt
, entãops ax
irá exibir uma linha que mostra um comando devi raven.txt
. Da mesma forma, se você digitar um comando comogrep snappr
, então,ps ax
será exibida uma linha que mostra um comando degrep snappr
. E, se você canalizar a saída desseps
meiogrep snappr
, agrep
encontrará a linha que está descrevendo a si mesmo . Então, se você digitarrepetidamente, ele imprimirá um número diferente a cada vez (porque está imprimindo o PID de
grep
, e você obtém umgrep
processo novo e exclusivo toda vez que executa o comando).Finalmente, considere: o
kill
comando não pode ser executado até que seus argumentos sejam conhecidos. Para que seu argumento seja conhecido, o$(ps ax | grep snappr | awk '{print $1}')
pipeline deve ter sido concluído. Isto implica que ogrep
deve ter terminado 1 . Portanto,kill
está sendo dado o PID dogrep
processo, mas somente após ogrep
processo ter terminado - então, naturalmente, ele reporta "Nenhum tal processo".Talvez eu devesse ter mencionado que não há
snappr
processo em execução. Se houvesse, seu primeiro comando produziria dois números: o PID desnappr
e o PID degrep snappr
. Agora, sesnappr
estava rodando, seu comando pode começar a rodar semi-corretamente, o que significa que ele faz o que você quer, mas também dá uma mensagem de erro. Se osnappr
está rodando com o PID 42097, egrep snappr
roda com o PID 70848, então okill
comando serákill 42097 70858
, o que irá matar osnappr
e obter uma mensagem de erro de tentar matar ogrep
processo que não existe mais.Você provavelmente vai querer melhorar isso. Meu jeito favorito, que eu inventei há 20 anos, é mudar o
grep
paragrep "[s]nappr"
, o qual vai combinarsnappr
mas não vai se igualar. Outra abordagem é usar empgrep
vez deps | grep
.1 Alternativamente, o
awk
poderia terminar se ogrep
meramente fechou sua stdout. Este seria um comportamento muito incomum para um programa * nix.fonte
PRIOR="$(ps --no-headers -Ao "pid,ppid,sid,args"|grep "$THIS"|grep -Ev "(grep |$PPID |$$ |<defunct>)")"
. Se $ PRIOR não for nulo, o script já está sendo executado. Eu tive mais sucesso com isso do que compgrep
.grep | grep -v
solução. Por que executar um processo extra que você não precisa? Trabalhe de maneira mais inteligente, não mais difícil.grep "[s]nappr"
solução? (2) Enquanto estamos falando de processos de morte, quem se importa se os processos defuntos estão incluídos? Matar um processo extinto é um no-op.Resposta mais curta
Não saltar através de aros Bash para matar
snappr
comps
, canalizada atravésgrep
e depois canalizada atravésawk
assim. Em vez disso tente matá-lo assim usandopkill
; sem confusão ou problemas e segmenta com base no nome do processo pronto para uso:Resposta mais longa
Não é muito claro como o Snapper opera em um nível de processo do sistema, mas o problema pode ser que você esteja apenas capturando o ID do processo filho em vez do ID do processo pai.
Na verdade, acredito que o método que você está usando para capturar um processo ID (
ps ax | grep snappr | awk '{print $1}'
) retornaria uma lista inteira de IDs de processo conectadas,snappr
independentemente de ser pai ou filho. Portanto, usando isso, você pode matar um ID de processo que é apenas um ID de processo filho, mas o ID pai ainda estaria ativo e capaz de "gerar" outro processo filho para compensar.Então, talvez você possa fazer algo assim para pegar o ID pai definitivo de qualquer ID de processo que você alimenta e age sobre ele; prova simples de conceito de como funciona:
Executar esse comando simples no Bash fornecerá o ID do processo pai do ID do processo filho inserido
[process ID]
. Portanto, se o ID filho4567
tiver um ID do processo pai123
, o comando será:E isso retornaria
123
.Dito isso, essa pode ser uma maneira perigosa de lidar com um processo de extravio, pois se o seu script pegar o ID do processo pai real
snapper
, então o pai desse ID de processo poderia ser realmente seu próprio Bash shell. Assim, você pode, inadvertidamente, simplesmente matar seu Bash shell em vez desnapper
derrubá-lo do sistema enquanto deixa osnapper
processo em execução.Mas tudo o que disse, porque não tornar sua vida mais fácil e apenas correr
pkill
assim:Isso matará todos os processos conectados
snappr
sem qualquer malabarismo de linha de comando.fonte
sudo
. E você não deve usarsudo
se você não precisa.grep
está se igualando.killall
vez de,pkill
por padrão,pkill
overkills.