Unikaj plików PID, cronów lub czegokolwiek innego, co próbuje ocenić procesy, które nie są ich dziećmi.
Istnieje bardzo dobry powód, dla którego w UNIX możesz TYLKO czekać na swoje dzieci. Każda metoda (ps parsowanie, pgrep, przechowywanie PID, ...), która próbuje obejść tę wadę i ma luki w niej. Po prostu powiedz nie .
Zamiast tego potrzebujesz procesu, który monitoruje proces, aby był jego rodzicem. Co to znaczy? Oznacza to, że tylko proces, który rozpoczyna proces, może niezawodnie czekać na jego zakończenie. W bashu jest to absolutnie trywialne.
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
Powyższy fragment kodu bash działa myserverw untilpętli. Pierwsza linia zaczyna się myserveri czeka na zakończenie. Po zakończeniu untilsprawdza status wyjścia. Jeśli status wyjścia to 0, oznacza to, że zakończył się z wdziękiem (co oznacza, że poprosiłeś go o zamknięcie i udało się to pomyślnie). W takim przypadku nie chcemy go ponownie uruchamiać (poprosiliśmy tylko o zamknięcie!). Jeśli status wyjścia nie jest 0, untiluruchomi ciało pętli, które emituje komunikat o błędzie na STDERR i ponownie uruchamia pętlę (powrót do linii 1) po 1 sekundzie .
Dlaczego czekamy sekundę? Ponieważ jeśli coś jest nie tak z sekwencją uruchamiania myserveri natychmiast ulega awarii, będziesz mieć bardzo intensywną pętlę ciągłego restartowania i awarii na rękach. Odciąża sleep 1to od tego napięcia.
Teraz wszystko, co musisz zrobić, to uruchomić ten skrypt bash (prawdopodobnie asynchronicznie), a on będzie go monitorował myserveri restartował w razie potrzeby. Jeśli chcesz uruchomić monitor przy rozruchu (dzięki czemu serwer „przetrwa” ponowne uruchomienie), możesz zaplanować go w cronie użytkownika (1) z @rebootregułą. Otwórz swoje reguły cron za pomocą crontab:
crontab -e
Następnie dodaj regułę, aby uruchomić skrypt monitorowania:
@reboot /usr/local/bin/myservermonitor
Alternatywnie; spójrz na inittab (5) i / etc / inittab. Możesz dodać tam linię, aby myserverzacząć od określonego poziomu inicjacji i automatycznie się odradzać.
Edytować.
Pozwól, że dodam kilka informacji o tym, dlaczego nie używać plików PID. Chociaż są bardzo popularne; są również bardzo wadliwe i nie ma powodu, dla którego nie zrobiłbyś tego po prostu we właściwy sposób.
Rozważ to:
Recykling PID (zabicie niewłaściwego procesu):
/etc/init.d/foo start: start foo, zapisz fooPID do/var/run/foo.pid
- Chwilę później:
foojakoś umiera.
- Chwilę później: każdy losowy proces, który się rozpoczyna (nazwij go
bar), przyjmuje losowy PID, wyobraź sobie, że bierze on foostary PID.
- Zauważyłeś
foo, że zniknął: /etc/init.d/foo/restartczyta /var/run/foo.pid, sprawdza, czy nadal żyje, znajduje bar, myśli, że to foozabija, zaczyna nowe foo.
Pliki PID stają się nieaktualne. Potrzebujesz nadmiernie skomplikowanej (lub powinienem powiedzieć, nietrywialnej) logiki, aby sprawdzić, czy plik PID jest nieaktualny i czy taka logika jest ponownie podatna na atak 1..
Co jeśli nie masz dostępu do zapisu lub jesteś w środowisku tylko do odczytu?
To bezcelowa nadmierna komplikacja; zobacz, jak prosty jest mój przykład powyżej. W ogóle nie trzeba tego komplikować.
Zobacz także: Czy pliki PID są nadal wadliwe, gdy robią to „dobrze”?
Tak poza tym; nawet gorzej niż parsowanie plików PID ps! Nigdy tego nie rób.
psjest bardzo nieprzenośny. Chociaż można go znaleźć w prawie każdym systemie UNIX; jego argumenty są bardzo różne, jeśli chcesz otrzymać niestandardowe dane wyjściowe. A standardowe wyjście jest WYŁĄCZNIE do spożycia przez ludzi, a nie do analizowania skryptów!
- Parsowanie
psprowadzi do wielu fałszywych trafień. Weźmy ps aux | grep PIDprzykład, a teraz wyobraźmy sobie, że ktoś zaczyna gdzieś proces z liczbą jako argumentem, który akurat jest taki sam jak PID, którym patrzyłeś na swojego demona! Wyobraź sobie, że dwie osoby rozpoczynają sesję X, a ty żartujesz, że X zabija twoją. To tylko wszelkiego rodzaju złe.
Jeśli nie chcesz sam zarządzać procesem; istnieje kilka doskonale dobrych systemów, które będą działać jako monitor twoich procesów. Zobacz na przykład runit .