Comment écrire un shscript pour tuer -9 un pid qui se trouve via lsof -i

29

J'utilise tomcat, et parfois quand je lui dis d'arrêter, il ne tue pas correctement le processus.

Mon chemin est aussi de faire:

lsof -i tcp:8080

qui génère:

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)

Je cours ensuite

kill -9 pid

Je veux un moyen d'obtenir tous les nombres pid et de les tuer. La chose est que je ne sais pas comment isoler ce champ.

user2757729
la source
1
Si vous êtes sûr de n'avoir qu'un seul tomcatprocessus ouvert, vous pouvez utiliserkillall -9 tomcat
Joseph R.

Réponses:

57

Il y a une -toption (concise) dans lsof, qui semble faire exactement ce que vous cherchez, c'est-à-dire

$ sudo lsof -ti tcp:80
1387
4538
4539

Voir 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.

En supposant que vous disposez des autorisations nécessaires, vous pouvez transmettre le résultat à killune liste de PID avec substitution de commande:

kill -9 $(lsof -ti tcp:80)
tournevis
la source
Vous avez maintenant répondu aux deux questions que j'ai posées à btw ;-)
user2757729
3

N'oubliez pas l' --no-run-if-emptyoption de tuer :)

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

De cette façon, kill ne sera exécuté qu'il y a un processus d'écoute, pas besoin de faire le contrôle vous-même.

SMF
la source
'--no-run-if-empty' n'est pas pris en charge dans BSD (mac)
dinesh ygv
1

lsof -i tcp:8080produit la sortie, puis | egrep -v "COMMAND PID USER"supprime la ligne d'en-tête, puis | awk '{print $2}'imprime le 2e champ, | sort -nprépare les nombres | uniq, qui ne sort qu'une seule fois chaque PID unique. Le rassemblement donne:

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

Mais, pkill -KILL tomcatou killall -KILL tomcatc'est plus facile.

waltinator
la source
Le processus Tomcat n'est pas nommé "tomcat", c'est le problème. C'est juste un processus java normal, un travail supplémentaire doit être fait pour identifier le processus correct s'il y a d'autres processus java en cours d'exécution en même temps.
Terry Wang
@TerryWang Yup, c'est aussi le problème que j'ai eu. La réponse de Steeldrivers fonctionne très bien.
user2757729
0

La doublure unique de @waltinator est géniale.

J'y ajouterai encore plus de saveur:

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)

REMARQUE: ceci est encore très basique, vous devrez peut-être ajouter plus de sel et de poivre pour le rendre plus robuste dans un environnement réel.

Terry Wang
la source
0

Ceci est le script que j'ai trouvé avec un peu de vérification d'erreur.

#!/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
la source
0

Voici une simple fonction de coquille de poisson

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

il suffit de coller ce meunier dans un fichier à cet endroit ~/.config/fish/functions/kill-port.fishet c'est bon. Vous pouvez l'appeler commekill-port 8000

codenamejames
la source