2013-04-01 18 views
10

Piszę procedurę zatrzymania dla skryptu usług rozruchu:Prevent proces od zabijania się używając pkill

do_stop() 
{ 
    rm -f $PIDFILE 
    pkill -f $DAEMON || return 1 
    return 0 
} 

Problemem jest to, że pkill (tak samo z killall) pasuje również proces reprezentujący sam skrypt i to w zasadzie się kończy. Jak to naprawić?

+0

użycie pgrep i pętli następnie zabić? –

+0

Zamierzałem to zrobić, ale zadałem to pytanie na wypadek, gdyby było prostsze rozwiązanie. – kaspersky

Odpowiedz

9

Można jawnie odfiltrować bieżącej PID z wynikami:

kill $(pgrep -f $DAEMON | grep -v ^$$\$) 

Aby prawidłowo użyć flagi -f, należy dostarczyć całą ścieżkę do demona, a nie tylko fragmentu. To uniemożliwi ci zabicie skryptu (i wyeliminowanie potrzeby powyższego grep), a także zabicie wszystkich innych procesów systemowych, które dzielą nazwę demona.

+0

Dzięki, to zadziałało bardzo dobrze. – kaspersky

+0

Dla mnie w bash 'pgrep' znajduje również pid podpowłoki i drukuje brzydkie ostrzeżenie, gdy próbuje go zabić. – rudimeier

6

pkill -f akceptuje pełne wyrażenie regularne. Więc zamiast pkill -f $DAEMON należy użyć:

pkill -f "^"$DAEMON 

Aby upewnić się tylko wtedy, gdy nazwa Proces rozpoczyna się od danej nazwy demona tylko wtedy jest on zabity.

Lepszym rozwiązaniem będzie zapisywanie pid (Proces Id) procesu w pliku po uruchomieniu procesu. Aby zatrzymać proces, po prostu przeczytaj plik, aby identyfikator procesu został zatrzymany/zabity.

1

Sądząc po twoim pytaniu, nie musisz się martwić używaniem pgrep i pkill, więc oto kilka innych powszechnie używanych opcji.

1) Użyj killproc z /etc/init.d/functions lub /lib/lsb/init-functions (która jest zawsze odpowiednia dla twojej dystrybucji i wersji Linuksa). Jeśli piszesz skrypt usługi, być może już dołączasz ten plik, jeśli użyłeś jednej z innych usług jako przykładu.

Usage: killproc [-p pidfile] [ -d delay] {program} [-signal] 

Główną zaletą korzystania z tego jest to, że wysyła SIGTERM, czeka, aby zobaczyć, czy proces kończy i wysyła SIGKILL tylko wtedy, gdy jest to konieczne.

2) Można również użyć tajnego sosu killproc, który polega na znalezieniu identyfikatorów procesu do zabicia przy użyciu pidof, który ma opcję -o do wykluczenia określonego procesu. Argumentem dla -o może być $$, bieżący identyfikator procesu lub %PPID, który jest specjalną zmienną, którą pidof interpretuje jako skrypt wywołujący pidof. Na koniec, jeśli demon jest skryptem, potrzebujesz -x, więc próbujesz zabić skrypt przez jego nazwę, zamiast zabijać bash lub python.

for pid in $(pidof -o %PPID -x progd); do 
    kill -TERM $pid 
done 

można zobaczyć przykład tego w artykule Bash: How to check if your script is already running

Powiązane problemy