Não é possível matar um processo em execução - mas aparentemente não visível - no gerenciador de tarefas

6

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
    
por aweeeezy 16.03.2015 / 06:25

2 respostas

17

Você percebeu que você tem dois PIDs diferentes nas duas tentativas?

Considere isso: se você digitar um comando como vi raven.txt , então ps ax exibirá uma linha que mostra um comando de vi raven.txt . Da mesma forma, se você digitar um comando como grep snappr , então ps ax exibirá uma linha que mostra um comando de grep snappr . E, se você canalizar a saída desse ps a grep snappr , o grep encontrará a linha que está descrevendo a si mesma . Então, se você digitar

$ ps ax | grep snappr | awk '{print $1}'

repetidamente, imprimirá um número diferente todas as vezes (porque está imprimindo o PID de grep , e você obtém um novo e exclusivo processo grep sempre que executar o comando.

Finalmente, considere: o comando kill não pode ser executado até que seu (s) argumento (s) seja (são) conhecido (s). Para que seu argumento seja conhecido, o $(ps ax | grep snappr | awk '{print $1}') pipeline deve ter concluído. Isto implica que o grep deve ter terminado 1 . Portanto, o kill está recebendo o PID do processo grep , mas somente após o processo grep ter terminado - então, naturalmente, ele relata "Nenhum tal processo".

Talvez eu devesse ter mencionado que não há nenhum processo snappr em execução. Se houvesse, seu primeiro comando produziria dois números: o PID de snappr , e o PID de grep snappr . Agora, se snappr estivesse em execução, seu comando poderia começar a ser executado semiretamente, pelo que quero dizer que faz o que você quer, mas também dá uma mensagem de erro. Se o snappr estiver sendo executado com o PID 42097 e grep snappr for executado com o PID 70848, então o comando kill será kill 42097 70858 , o que matará o snappr e receba uma mensagem de erro ao tentar eliminar o processo grep que não existe mais.

Você provavelmente desejará melhorar isso. Meu jeito favorito, que eu inventei 20 anos atrás, para alterar o grep para grep "[s]nappr" , que corresponderá a snappr , mas não corresponderá a si mesmo. Outra abordagem é usar pgrep em vez de ps | grep .

1 Alternativamente, o awk poderia terminar se o grep simplesmente fechasse sua stdout. Esse seria um comportamento muito incomum para um programa * nix.

    
por 16.03.2015 / 07:10
8

Resposta mais curta

Não pule nos aros do Bash para matar snappr com ps , canalizado para grep e, em seguida, canalizado para awk desse modo. Em vez disso tente matá-lo assim usando pkill ; não muss ou fuss e metas com base no nome do processo fora da caixa:

sudo pkill snappr

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 pegando o ID do processo filho em vez de o ID do processo pai.

Na verdade, acredito que o método que você está usando para pegar um ID de processo ( ps ax | grep snappr | awk '{print $1}' ) retornaria uma lista inteira de IDs de processo conectadas a snappr , independentemente de ser pai ou filho. Portanto, o uso de talvez mate um ID de processo que seja 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:

ps -p [process ID] -o ppid=

A execução desse comando simples no Bash fornecerá o ID do processo pai do ID do processo filho que você colocou em [process ID] . Portanto, se a ID da criança 4567 tiver um ID do processo pai de 123 , o comando será:

ps -p 4567 -o ppid=

E isso retornaria, 123 .

Dito isso, essa pode ser uma maneira perigosa de lidar com um processo perdido, pois se o seu script pegar o ID do processo pai real de snapper , o pai desse ID de processo poderia ser seu próprio Bash shell. Assim, você pode, inadvertidamente, simplesmente matar seu Bash shell em vez do snapper derrubá-lo do sistema, deixando o processo snapper em execução.

Mas tudo isso dito, por que não facilitar sua vida e simplesmente executar pkill assim:

sudo pkill snappr

Isso eliminará todos os processos conectados a snappr sem nenhum malabarismo de linha de comando.

    
por 16.03.2015 / 07:21

Tags