Jaki jest właściwy sposób sprawdzenia, czy PID działa?

12

Mam .pidplik i muszę sprawdzić, czy proces jest uruchomiony. Do tej pory znalazłem dwie opcje

kill -0 `cat something.pid`

który wypisuje błąd, jeśli pid nie działa. Wiem, że można to przekierować /dev/null, ale sprawia, że ​​myślę, że nie jest to najlepsze rozwiązanie.

Drugim rozwiązaniem byłoby użycie ps, które jednak drukuje również na STDOUT

ps -ef `cat something.pid`

Czy przekierowanie wyjścia /dev/nulli zwyczajne użycie zwróconego kodu stanu jest normalne , czy jest to znak, że robię coś źle i potrzebuję innego polecenia?

Jakub Arnold
źródło
5
Używaj kill -0tak, jak jest to zgodne ze standardem (POSIX).
Anders

Odpowiedzi:

10

w przypadku większości dystrybucji Linuksa wyliczenie / proc / {pid} jest dobrym sposobem na uzyskanie informacji o uruchomionych procesach i zwykle o tym, jak polecenia przestrzeni użytkownika, takie jak „ps”, komunikują się z jądrem. Na przykład możesz to zrobić;

[ -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"

Edycja: powinieneś sprawdzić, czy kpid jest ustawiony, ale jest to bardziej przydatne, ponieważ zwróci „nie istnieje” dla unset $ {kpid}

[ -n "${kpid}" -a -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"
Tom H.
źródło
@ SteveMuster Dzięki temu odpowiedź byłaby specyficzna dla systemu Linux. W systemie OSX nie ma opcji / proc. I myślę, że nie ma / proc na BSD.
popiół
Pamiętaj, że musisz upewnić się, że ${kpid}istnieje
Wilf
@ Wilko edytowałem, więc zwraca „proces nie istnieje” dla unset $ {kpid}
Tom H
Dzięki - robiłem skrypt, który sprawdza PID przy użyciu podobnej metody i nie działał, dopóki nie znalazłem, że to był problem :)
Wilf
6

Jak zauważył Anders, powinieneś używać kill -0do zachowania zgodności z POSIX.

W systemach Linux można również sprawdzić, czy istnieje plik w systemie plików / proc, np.

-f /proc/$(cat something.pid)/status
cjc
źródło
1

Jeśli jest to w skrypcie (który, jak zakładam, jest tak, ponieważ martwisz się drukowaniem na standardowe wyjście), możesz to zrobić w następujący sposób:

if ps -p $(cat something.pid) > /dev/null 2>&1
then
    kill $(cat something.pid)
else
    # Deal with the fact that the process isn't running
    # i.e. clear up the pid file
fi

Do ps -pszuka proces z PID określonej w something.pid (the $()składnia jest nieco nowsza wersja grawis. Grawis potrzebuje ucieczki w pewnych okolicznościach, które nowa forma nie). Do 2>&1przekierowania stderr do tego polecenia, jak również.

Jeśli ps -ppolecenie nie znajdzie procesu z tym PID, kończy działanie z błędem> 0, a więc elsezostaje wykonane. W przeciwnym razie killoświadczenie. Możesz negować powyższe, jeśli chcesz, wykonując:

if ! ps -p ...

Mam nadzieję, że to odpowiada na twoje pytanie. Oczywiście używaj niebezpiecznych poleceń, takich jak kill.

webtoe
źródło
1

Oto kilka opcji:

  • Jeśli piszesz skrypt inicjujący (np. Ten, w którym chcesz umieścić /etc/init.d/) i korzystasz z dystrybucji opartej na Debianie, lepiej użyj start-stop-daemon:
    # start-stop-daemon -T -p $PIDFILE -u $USER_NAME -n $NAME
    Powinieneś otrzymać kod wyjścia 0, jeśli jest uruchomiony.
  • Możesz użyć pgrep i pkill z procpspakietu:
    pgrep --pidfile $PIDFILE
Jolly Roger
źródło
0

Jeśli masz plik pid, możesz użyć pgrep, aby sprawdzić, czy proces jest uruchomiony:

    if pgrep -F something.pid; then
        echo "Running"
    else
        echo "Not running"
    fi
Dima L.
źródło