Piszę skrypt Perla, który analizuje pliki dziennika w celu zebrania PID, a następnie sprawdza, czy ten PID jest uruchomiony. Próbuję wymyślić najlepszy sposób na sprawdzenie tego. Oczywiście mógłbym zrobić coś takiego:
system("ps $pid > /dev/null") && print "Not running\n";
Jednak wolę unikać połączenia systemowego, jeśli to możliwe. Dlatego pomyślałem, że mogę użyć /proc
systemu plików (przenośność nie stanowi problemu, zawsze będzie działał w systemie Linux). Na przykład:
if(! -d "/proc/$pid"){
print "Not running\n";
}
Czy to jest bezpieczne? Czy zawsze mogę założyć, że jeśli nie ma /proc/$pid/
katalogu, powiązany PID nie jest uruchomiony? Spodziewam się tego, skoro i tak AFAIK ps
sam otrzymuje informacje, /proc
ale ponieważ dotyczy to kodu produkcyjnego, chcę być pewien.
Czy mogą więc wystąpić przypadki, w których uruchomiony proces nie ma /proc/PID
katalogu lub /proc/PID
katalog istnieje, a proces nie jest uruchomiony? Czy istnieje powód, dla którego wolisz parsowanie ps
niż sprawdzanie istnienia katalogu?
źródło
kill
funkcja perla wykorzystująca sygnał 0, który nie zabija, ale mówi, czy możesz to zrobić (tzn. potrzebujesz zgody na sygnalizowanie tego procesu).kill -0
jest najlepsza), to powie ci tylko, czy jest uruchomiony proces z danym PID . Nie mówi ci, czy proces będzie nadal działał o jedną milisekundę później, ani nie mówi, czy jest to proces, który Cię interesuje, czy proces niepowiązany, któremu przypisano ten sam PID po śmierci interesującego procesu . Prawie zawsze błędem jest sprawdzenie, czy dany PID działa : jest bardzo niewiele okoliczności, w których nie jest to podatne na warunki wyścigowe.Odpowiedzi:
kill(0,$pid)
Można użyć funkcji perla .Jeśli kod powrotu to 1, wówczas istnieje PID i można do niego wysłać sygnał.
Jeśli kod powrotu to 0, musisz sprawdzić $ !. Może to być EPERM (odmowa dostępu), co oznacza, że proces istnieje lub ESRCH, w którym to przypadku proces nie istnieje.
Jeśli Twój kod sprawdzający jest uruchomiony,
root
możesz to uprościć, sprawdzając tylko kod powrotu kill; 0 => błąd, 1 => okNa przykład:
Można to zrobić w prostą funkcję
źródło
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
coś podobnego. Bardziej podoba mi się twojeErrno
rozwiązanie, dzięki. Chociaż prawdopodobnie pójdę z tym, poczekam chwilę, aby ktokolwiek mógł odpowiedzieć na podstawowe pytanie dotyczące Linuksa./proc
jest zamontowany, to każdy PID widoczny w przestrzeni nazw będzie obecny, więc-d /proc/$pid
test będzie działał ... ale wymaga wyjścia do systemu plików zamiast używania rodzimych wywołań systemowych.system
wywołanie” - tj. wywołaniesystem
samej funkcji, a nie „wywołanie systemowe” . Tego drugiego nie da się uniknąć, ale pierwszego z pewnością można. Ma to teraz sens!/proc/PID
kill 0
/proc
/proc
ps
top
ilsof
prawdopodobnie nie będzie działać - i tak to może nie być problemem dla systemu produkcyjnego. Ale (teoretycznie) jest możliwe, że nigdy nie został zamontowany (chociaż może to uniemożliwić przywrócenie systemu do normalnego stanu), z pewnością jest możliwe odmontowanie go (przetestowałem go 1) i uważam, że nie ma żadnej gwarancji, że będzie istnieć (tj. nie jest wymagana przez POSIX). I, chyba że system jest całkowicie zamknięty,kill
będzie działał./proc
wymaga czytania katalogu root znaleźć się/proc
system plików. Dotyczy to każda próba dostępu do dowolnego pliku bezwzględną ścieżkę, w tym rzeczy w/bin
,/etc
i/dev
. Zdarza się to tak często, że katalog główny jest z pewnością buforowany w pamięci przez cały okres życia (czas działania) systemu, więc ten krok można wykonać bez żadnego wejścia / wyjścia dysku. A kiedy już będziesz miał igłę/proc
, wszystko, co się wydarzy, jest w pamięci./proc
? Zstat
,open
,readdir
, itd., Które są rodzimym systemem nazywa każdy kawałek jakkill
.Pytanie dotyczy trwającego procesu. To jest śliskie zdanie. Jeśli naprawdę chcesz przetestować, czy proces jest uruchomiony (tj. W kolejce uruchomieniowej; może bieżący proces na jakimś procesorze; nie śpi, nie czeka lub nie jest zatrzymany), może być konieczne wykonanie a i odczytanie wyniku lub spojrzenie na . Ale nie widzę żadnej wskazówki w twoim pytaniu lub komentarzach, że zajmujesz się tym.
ps PID
/proc/PID/stat
Słoń w pokoju jest jednak taki, że proces zombie 2 może być trudny do odróżnienia od procesu, który jest żywy i ma się dobrze.
kill 0
działa na zombie i istnieje. Możesz zidentyfikować zombie za pomocą technik wymienionych w poprzednim akapicie (robienie i czytanie wyników lub patrzenie ). My bardzo szybkie i dorywczo (czyli niezbyt dokładny) badanie sugeruje, że można to zrobić także przez robi lub na , lub - to nie powiedzie się na zombie. (Zawiodą jednak również w przypadku procesów, których nie posiadasz)./proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1 gdy
-f
( m rozwiązaniem Orce) nie pomoże,-l
( l azy).2 tj. Proces, który zakończył / zmarł / zakończył, ale którego rodzic jeszcze nie zrobił
wait
.źródło
kill(2)
wskazuje bezpośrednio na zachowanie, które wskazałeś, ale takperlfunc
jest. Wyślę do Michaela Kerriska e-maila, aby zobaczyć, co ma on do powiedzenia na stronie systemowej.kill(2)
kill(2)
podręcznika (nie widzę go jeszcze online): „Jeśli sig ma wartość 0, to nie jest wysyłany żaden sygnał, ale nadal wykonywane są kontrole istnienia i uprawnień; można tego użyć do sprawdzenia istnienia identyfikator procesu lub identyfikator grupy procesów, które osoba dzwoniąca może zasygnalizować. ”