Як написати shscript, щоб знищити -9 pid, який можна знайти через lsof -i


29

Я використовую tomcat, а іноді, коли я кажу йому зупинити, це не вбиває належним чином процес.

Мій спосіб цього теж зробити:

lsof -i tcp:8080

який виводить:

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)

Я тоді біжу

kill -9 pid

Я хочу, щоб дістати всі номери pid і вбити їх. Річ у тому, що я не знаю, як ізолювати це поле.


1
Якщо ви впевнені, що у вас tomcatвідкритий лише один процес, ви можете використовуватиkillall -9 tomcat
Джозеф Р.

Відповіді:


57

Існує -t(короткий) варіант в lsof, який, здається, робить саме те, що ви шукаєте, тобто

$ sudo lsof -ti tcp:80
1387
4538
4539

Побачити 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.

Припускаючи, що у вас є необхідні дозволи, ви можете передати результат killяк список PID з підстановкою команд:

kill -9 $(lsof -ti tcp:80)

Тепер ви відповіли на обидва запитання, які я задавав btw ;-)
user2757729

3

Не забувайте --no-run-if-emptyваріант вбивства :)

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

Таким чином вбивство буде запускатися лише там, де прослуховується процес, не потрібно робити перевірку самостійно.


'--no-run-if-empty' не підтримується в BSD (mac)
dinesh ygv

1

lsof -i tcp:8080виробляє вихід, потім | egrep -v "COMMAND PID USER"опускає заголовок рядка, потім | awk '{print $2}'друкує 2-е поле, | sort -nготує числа для | uniq, яке виводить кожен унікальний PID один раз. З'єднання все це дає:

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

Але, pkill -KILL tomcatабо killall -KILL tomcatпростіше.


Процес Tomcat не названий "tomcat", ось у чому проблема. Це просто звичайний процес Java, додаткова робота повинна бути виконана для виявлення правильного процесу, якщо одночасно працюють і інші процеси Java.
Террі Ван

@TerryWang Yup, в цьому і в мене була проблема. Відповідь Steeldrivers чудово працює.
user2757729

0

Один лайнер від @waltinator чудовий.

Я додам до нього ще трохи аромату:

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

АБО

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

ПРИМІТКА. Це все ще дуже просто, можливо, вам потрібно буде додати більше солі та перцю, щоб зробити його більш надійним у реальному середовищі.


0

Цей сценарій я придумав трохи перевірки помилок.

#!/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

0

Ось проста функція шкаралупи риби

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

просто вставте цю присоску у файл у цьому місці ~/.config/fish/functions/kill-port.fishта ваше добро. Ви можете назвати це якkill-port 8000

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.