Jak sprawdzić, czy istnieje identyfikator procesu (PID)

W skrypcie bash, chcę wykonać następujące (w pseudo-kodzie):

if [ a process exists with $PID ]; then

    kill $PID 

fi

Jakie jest odpowiednie wyrażenie dla instrukcji warunkowej?

Author: codeforester, 2010-06-15

9 answers

Aby sprawdzić istnienie procesu, użyj

kill -0 $pid

Ale tak jak powiedział @unwind, jeśli i tak zamierzasz go zabić, po prostu

kill $pid

Albo będziesz miał stan rasy.

Jeśli chcesz zignorować tekst wyjściowy kill i zrobić coś na podstawie kodu wyjścia, możesz

if ! kill $pid > /dev/null 2>&1; then
    echo "Could not send SIGTERM to process $pid" >&2
fi
 138
Author: Christoffer Hammarström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 08:10:02

Najlepszy sposób to:

if ps -p $PID > /dev/null
then
   echo "$PID is running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
fi

Problem z:

kill -0 $PID

Czy kod wyjścia będzie niezerowy, nawet jeśli pid jest uruchomiony i nie masz prawa go zabić. Na przykład:

kill -0 1

I

kill -0 $non-running-pid

Mają nieodróżnialny (niezerowy) kod zakończenia dla normalnego użytkownika, ale proces init (PID 1) z pewnością działa.

Dyskusja

Odpowiedzi omawiające warunki zabijania i rasy są dokładnie właściwe, jeśli ciało testu jest "zabójstwem". Przyszedłem. szukając ogólnego " Jak testować istnienie PID W bash ".

Metoda / proc jest interesująca, ale w pewnym sensie łamie ducha abstrakcji poleceń "ps", tzn. nie trzeba szukać w /proc, bo co jeśli Linus zdecyduje się wywołać plik " exe " coś innego?

 210
Author: FDS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-02 21:29:31
if [ -n "$PID" -a -e /proc/$PID ]; then
    echo "process exists"
fi

Lub

if [ -n "$(ps -p $PID -o pid=)" ]

W tej ostatniej formie {[2] } jest formatem wyjściowym do wyświetlania tylko kolumny ID procesu bez nagłówka. Cudzysłowy są niezbędne , aby niepusty operator Łańcuchowy -n dał poprawny wynik.

 53
Author: user2683246,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 08:36:59

ps polecenie z -p $PID może to zrobić:

$ ps -p 3531
  PID TTY          TIME CMD
 3531 ?        00:03:07 emacs
 26
Author: oherrala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-01 11:41:05

Masz dwa sposoby:

Zacznijmy od szukania konkretnej aplikacji w moim laptopie:

[root@pinky:~]# ps fax | grep mozilla
 3358 ?        S      0:00  \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2    S+     0:00              \_ grep mozilla

Wszystkie przykłady będą teraz szukać PID 3358.

Pierwszy sposób : Uruchom "ps aux" i grep dla PID w drugiej kolumnie. W tym przykładzie Szukam Firefoksa, a potem PID:

[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358

Więc Twój kod będzie:

if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
    kill $PID 
fi

Drugi sposób : po prostu poszukaj czegoś w katalogu /proc/$PID. W tym przykładzie używam "exe" , ale możesz użyć wszystkiego else.

[root@pinky:~]# ls -l /proc/3358/exe 
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash

Więc Twój kod będzie:

if [ -f /proc/$PID/exe ]; then
    kill $PID 
fi

BTW: co jest nie tak z kill -9 $PID || true?


EDIT:

Po przemyśleniu tego przez kilka miesięcy.. (około 24...) oryginalny pomysł dałem tutaj jest ładny hack, ale bardzo nieportable. Chociaż uczy kilku szczegółów implementacji Linuksa, nie będzie działać na Mac, Solaris lub * BSD. Może nawet zawieść w przyszłych jądrach Linuksa. Proszę-użyj "ps", jak opisano w innych odpowiedziach.

 10
Author: elcuco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-02 11:10:56

Myślę, że to złe rozwiązanie, które otwiera się na warunki wyścigowe. Co jeśli proces umrze między Twoim testem a Twoim wezwaniem do zabijania? Więc zabijanie zawiedzie. Dlaczego więc nie spróbować zabić we wszystkich przypadkach i sprawdzić jego wartość zwrotną, aby dowiedzieć się, jak poszło?

 7
Author: unwind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-15 09:32:48

It seems like you want

wait $PID

Który powróci po zakończeniu $pid.

W przeciwnym razie możesz użyć

ps -p $PID

, aby sprawdzić, czy proces nadal żyje (jest to bardziej efektywne niż kill -0 $pid, ponieważ zadziała nawet jeśli nie posiadasz pid).

 3
Author: Gagan Gami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-19 09:00:41

Tutaj zapisuję PID w pliku o nazwie .pid (czyli coś jak / run/...) i wykonaj skrypt tylko wtedy, gdy nie jest już wykonywany.

#!/bin/bash
if [ -f .pid ]; then
  read pid < .pid
  echo $pid
  ps -p $pid > /dev/null
  r=$?
  if [ $r -eq 0 ]; then
    echo "$pid is currently running, not executing $0 twice, exiting now..."
    exit 1
  fi
fi

echo $$ > .pid

# do things here

rm .pid

Uwaga: istnieje warunek rasy, ponieważ nie sprawdza, jak nazywa się ten pid. jeśli system jest restartowany i .pid istnieje, ale jest używany przez inną aplikację, co może prowadzić do "nieprzewidzianych konsekwencji".

 0
Author: invalidmagic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 15:41:40

Na przykład w GNU / Linuksie możesz użyć:

Pid=$(pidof `process_name`)

if [ $Pid > 0 ]; then

   do something
else

   do something
fi 

Lub coś w rodzaju

Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN

I to pokazuje nazwę aplikacji, tylko nazwę Bez ID.

 0
Author: inukaze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-02 17:42:29