Comando para matar o PID específico fornecido pelo comando anterior

3

Às vezes eu preciso matar um processo (as razões pelas quais não são importantes). E sei que posso encontrar esse processo com o seguinte comando: lsof -i :8080 , sendo meu candidato o último processo na tabela de saída.

Por exemplo, se eu executar o comando, uma saída como essa aparecerá:

COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
java    15112 dani   70u  IPv4 3178183      0t0  TCP localhost:39998->localhost:http-alt (CLOSE_WAIT)
java    15112 dani  137u  IPv4 3181607      0t0  TCP localhost:39999->localhost:http-alt (CLOSE_WAIT)
java    15112 dani  138u  IPv4 3181608      0t0  TCP localhost:40000->localhost:http-alt (CLOSE_WAIT)
java    15112 dani  139u  IPv4 3181609      0t0  TCP localhost:40001->localhost:http-alt (CLOSE_WAIT)
java    15112 dani  140u  IPv4 3181610      0t0  TCP localhost:40002->localhost:http-alt (CLOSE_WAIT)
java    19509 dani   50u  IPv6 4617361      0t0  TCP *:http-alt (LISTEN)
java    19509 dani   52u  IPv6 6642445      0t0  TCP localhost:http-alt->localhost:42996 (CLOSE_WAIT)

Então, meu alvo será o PID 19509 . Usando canos, como posso escolher o PID da última linha?

Eu quero alcançar um comando como lsof -i :8080 | something here to get the PID | kill -9

Estou executando o Linux Mint KDE x64

    
por Dani Sancas 02.05.2015 / 01:53

1 resposta

4

Respondendo sua pergunta literalmente, aqui está uma maneira de listar o último PID exibido por lsof :

lsof … | awk 'END {print $2}'

O Awk é uma linguagem de processamento de texto que lê os dados e os processa linha por linha. No código, END {…} executa o código nas chaves depois que toda a entrada é processada e opera efetivamente na última linha. $2 é o segundo campo delimitado por espaço em branco na linha.

E aqui estão algumas maneiras de matá-lo (cada linha funciona por conta própria):

kill $(lsof … | awk 'END {print $2}')
lsof … | awk 'END {print $2}' | xargs kill
lsof … | awk 'END {system("kill " $2)}'

No entanto, discuto sua afirmação de que o processo correto para matar é sempre o último. lsof exibe processos aumentando o PID, o que não faz sentido. Mesmo em sistemas nos quais IDs de processo são atribuídos sequencialmente (o que não é o caso em todas as variantes do Unix, nem mesmo em todas as instalações do Linux), eles são agrupados assim que atingem o valor máximo (normalmente 32767). Assim, decidir entre processos comparando PIDs não tem sentido.

Você precisa de algumas outras informações para decidir qual processo deve ser eliminado. Dependendo do tipo de informação que você está procurando e se você pode ter uma saída que contenha caracteres “estranhos” (como espaços em nomes de arquivos ou programas), você pode usar uma ferramenta como awk para processar a saída de lsof ou você pode usar a opção -F para lsof , que produz saída que é um pouco mais difícil de analisar em casos simples, mas (quase) não propensa a ambigüidade e mais fácil de analisar de maneira robusta. Por exemplo, se você quiser matar qualquer processo que esteja escutando na porta 8080, veja como você pode fazer isso:

lsof -n -i :8080 -F | awk '
    sub(/^p/,"") {pid = $0}
    $0 == "n*:http-alt" {print pid}
' | xargs kill

A chamada para a função sub substitui p no início de uma linha por uma cadeia vazia. Se esta substituição for executada, o bloco de código {pid = $0} será executado; Dessa forma, a variável pid contém o último valor de PID exibido por lsof . A segunda linha awk imprime o valor da variável pid se a linha for exatamente "n*:http-alt" , que é o caminho do lsof para relatar um soquete escutando na porta 8080 em todas as interfaces.

Este critério em particular, na verdade, não requer qualquer análise (eu mostrei apenas acima como exemplo). Você pode fazer com que lsof display apenas processe a escuta na porta especificada:

lsof -n -a -iTCP:8080 -sTCP:LISTEN -Fp | sed 's/^p//' | xargs kill

Ou, para isso, você pode usar netstat em seu lugar.

netstat -lnpt | awk '$4 ~ /:8080$/ {sub(/\/.*/, "", $7); print $7}'

Explicação do código awk: se a quarta coluna terminar com :8080 , substitua tudo após o primeiro / na sétima coluna (para remover a parte do nome do processo e mantenha apenas a parte PID) e imprima-a.

    
por 02.05.2015 / 02:18