W skrypcie bash chcę wykonać następujące czynności (w pseudo-kodzie):
if [ a process exists with $PID ]; then
kill $PID
fi
Jakie jest odpowiednie wyrażenie dla instrukcji warunkowej?
Aby sprawdzić istnienie procesu, użyj
kill -0 $pid
Ale tak jak powiedział @unwind, jeśli i tak chcesz go zabić, po prostu
kill $pid
lub będziesz mieć stan wyścigu.
Jeśli chcesz zignorować tekst kill
i zrobić coś na podstawie kodu wyjścia, możesz to zrobić
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill
jest nieco źle nazwany, ponieważ niekoniecznie zabija proces. Po prostu wysyła sygnał do procesu.kill $PID
jest równoważne zkill -15 $PID
wysyłaniem sygnału 15 SIGTERM do procesu, który jest instrukcją kończącą. Nie ma sygnału 0, jest to specjalna wartość informująca,kill
czy po prostu można wysłać sygnał do procesu, co w większości przypadków jest mniej więcej równoznaczne ze sprawdzeniem, czy istnieje. Zobacz linux.die.net/man/2/kill i linux.die.net/man/7/signalkill -0
, w rzeczywistości muszę to zrobić:kill -0 25667 ; echo $?
- a następnie, jeśli otrzymam zwrot0
, wówczas proces z tym PID może zostać zabity; a jeśli proces PID (powiedzmy) nie istnieje,$?
będzie1
, co oznacza awarię. Czy to jest poprawne?Najlepszym sposobem jest:
Problem z:
oznacza, że kod wyjścia będzie różny od zera, nawet jeśli pid jest uruchomiony i nie masz uprawnień, aby go zabić. Na przykład:
i
mają nie dający się odróżnić (niezerowy) kod wyjścia dla zwykłego użytkownika, ale proces inicjowania (PID 1) na pewno działa.
DYSKUSJA
Odpowiedzi omawiające zabójstwo i warunki wyścigu są dokładnie właściwe, jeśli testem jest „zabójstwo”. Przyszedłem szukać ogólnego „ jak testujesz istnienie PID w bash ”.
Metoda / proc jest interesująca, ale w pewnym sensie łamie ducha abstrakcji polecenia „ps”, tzn. Nie musisz szukać w / proc, ponieważ co, jeśli Linus zdecyduje się nazwać plik „exe” czymś innym?
źródło
-p
jest to niepotrzebne, przynajmniej w takim przypadku.ps $PID
ma dokładnie taki sam wynik.lub
W tej ostatniej formie
-o pid=
format wyjściowy wyświetla tylko kolumnę ID procesu bez nagłówka. Cudzysłowy są niezbędne, aby niepusty operator łańcuchowy-n
dawał poprawny wynik.źródło
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
opcje i funkcje różnią się w zależności od platformy, więc wciąż nie jest w pełni przenośny.$PID
jest pusty, to[ -e /proc/$PID ]
nadal zwróci true, ponieważ/proc/
katalog nadal istnieje.ps
polecenie z-p $PID
może to zrobić:źródło
Masz dwa sposoby:
Zacznijmy od szukania konkretnej aplikacji na moim laptopie:
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 firefox, a następnie PID:
Twój kod będzie więc:
Drugi sposób : poszukaj czegoś w
/proc/$PID
katalogu. W tym przykładzie używam „exe”, ale możesz użyć wszystkiego innego.Twój kod będzie więc:
BTW: co jest nie tak
kill -9 $PID || true
?EDYTOWAĆ:
Po przemyśleniu tego przez kilka miesięcy .. (około 24 ...) oryginalny pomysł, który tu podałem, to niezły hack, ale wysoce niemożliwy do przeniesienia. Chociaż uczy kilku szczegółów implementacji systemu Linux, nie będzie działać na komputerach Mac, Solaris lub * BSD. Może nawet zawieść w przyszłych jądrach Linuksa. Proszę - użyj „ps” jak opisano w innych odpowiedziach.
źródło
/proc/$PID/exe
nie jest zwykłym plikiem. Tak więc[ -f /proc/$PID/exe ]
zawsze zwracafalse
wynik. Spróbować[ -h /proc/$PID/exe ]
.Wygląda na to, że chcesz
który wróci po
$pid
zakończeniu.W przeciwnym razie możesz użyć
aby sprawdzić, czy proces jest nadal aktywny (jest to bardziej skuteczne niż
kill -0 $pid
ponieważ będzie działać, nawet jeśli nie jesteś właścicielem pid).źródło
pid 123 is not a child of this shell
Myślę, że to złe rozwiązanie, które otwiera się na warunki wyścigowe. Co się stanie, jeśli proces umrze między testem a wezwaniem do zabicia? Wtedy zabicie się nie powiedzie. Dlaczego więc nie spróbować zabić we wszystkich przypadkach i sprawdzić jego wartość zwracaną, aby dowiedzieć się, jak poszło?
źródło
kill -9
. To natychmiast zabija proces, nie dając mu szansy na posprzątanie po sobie. Zamiast tego użyjkill
odpowiednikakill -15
. Jeśli to nie zadziała, powinieneś dowiedzieć się, dlaczego i tylko w ostatecznościkill -9
.tutaj przechowuję PID w pliku o nazwie .pid (który jest podobny do / run / ...) i wykonuję skrypt tylko wtedy, gdy jeszcze nie jest wykonywany.
Uwaga: istnieje warunek wyścigu, ponieważ nie sprawdza on, jak nazywany jest ten pid. jeśli system zostanie zrestartowany, a plik pid istnieje, ale jest używany przez inną aplikację, może to prowadzić do „nieprzewidzianych konsekwencji”.
źródło
Na przykład w GNU / Linux możesz użyć:
Lub coś w tym rodzaju
i to pokazuje nazwę aplikacji, tylko nazwę bez identyfikatora.
źródło
pidof
nie zwraca liczby ujemnej, ponieważ ujemny PID nie ma sensu i nie możesz zabićinit
, więc twoje warunkowe nie ma sensu (a poza tym musisz uciec przed,>
aby uniemożliwić przekierowanie). Chcesz sprawdzić pusty wynik, ale oczywiście, jak każde przyzwoite narzędzie,pidof
ustawia kod wyjścia informujący, czy zadziałał, więc właściwym rozwiązaniem jestif Pid=$(pidof 'process_name'); then ...
lub (jeśliPid
później nie będziesz potrzebować tej wartości ) po prostuif pidof 'process_name'; then...
pidof
przykład jest pełen nieporozumień na temat tego, jaktest
działa bash . gnu.org/software/bash/manual/html_node/…poniższy kod sprawdza, czy mój proces jest uruchomiony, jeśli tak, nic nie rób.
sprawdzajmy nowe wiadomości z Amazon SQS co godzinę i tylko wtedy, gdy proces nie jest uruchomiony.
źródło