Как правильно проверить, работает ли PID?

12

У меня есть .pidфайл, и мне нужно проверить, запущен ли процесс. Пока я нашел два варианта

kill -0 `cat something.pid`

который выводит ошибку, если pid не запущен. Я знаю, что это может быть перенаправлено /dev/null, но это заставляет меня думать, что это не лучшее решение.

Вторым решением будет использование ps, которое также печатает на STDOUT

ps -ef `cat something.pid`

Это нормально, чтобы перенаправить вывод /dev/nullи просто использовать возвращенный код состояния, или это признак того, что я делаю что-то не так и мне нужна другая команда?

Якуб Арнольд
источник
5
Используйте kill -0как стандарт (POSIX) -совместимый.
Андерс
связанные: stackoverflow.com/questions/3043978/…
wisbucky

Ответы:

9

для большинства дистрибутивов linux перечисление / proc / {pid} является хорошим способом получения информации о запущенных процессах и обычно о том, как команды пользовательского пространства, такие как "ps", взаимодействуют с ядром. Так, например, вы можете сделать;

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

Изменить: вы должны проверить, что kpid установлен, но это более полезно, так как он вернет "не существует" для неустановленного $ {kpid}

[ -n "${kpid}" -a -d "/proc/${kpid}" ] && echo "process exists" || echo "process not exists"
Том Х
источник
@SteveMuster Это сделало бы ответ для конкретного Linux. На OSX нет / proc. И я думаю, что нет / proc на BSD.
ясень
Обратите внимание, с этим вам нужно убедиться, что он ${kpid}существует
Уилф
@Wilf Я отредактировал его, поэтому он возвращает «процесс не существует» для unset $ {kpid}
Том Х
Спасибо - я делал сценарий, который проверяет PID с использованием аналогичного метода, и он не работал, пока я не обнаружил, что это проблема :)
Уилф
6

Как отметил Андерс, вы должны использовать kill -0для соответствия POSIX.

В системах Linux вы также можете проверить наличие файла в файловой системе / proc, например:

-f /proc/$(cat something.pid)/status
CJC
источник
1

Если это в сценарии (что, как я полагаю, имеет место в связи с тем, что вы беспокоитесь о печати на стандартный вывод), то вы могли бы сделать следующее:

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

В ps -pвыглядит для процесса с PID , указанной в something.pid ( $()синтаксис немного более новая версия кавычки. Кавычка необходимо избежать при определенных обстоятельствах, новая форма не делает). Также 2>&1перенаправляет stderr для этой команды.

Если ps -pкоманда не находит процесс с этим PID, она завершается с ошибкой> 0, и поэтому elseвыполняется. В противном случае killутверждение. Вы можете отрицать вышесказанное, если хотите:

if ! ps -p ...

Надеюсь это ответит на твой вопрос. Очевидно, будьте осторожны и проверяйте много, используя опасные команды, такие как kill.

webtoe
источник
1

Вот несколько вариантов:

  • Если вы пишете сценарий инициализации (например, тот, который нужно разместить /etc/init.d/) и используете дистрибутив на основе Debian, вам лучше использовать start-stop-daemon:
    # start-stop-daemon -T -p $PIDFILE -u $USER_NAME -n $NAME
    Вы должны получить код выхода 0, если он работает.
  • Вы можете использовать pgrep и pkill из procpsпакета:
    pgrep --pidfile $PIDFILE
Веселый Роджер
источник
0

Если у вас есть pid-файл, вы можете использовать pgrep, чтобы проверить, запущен ли процесс:

    if pgrep -F something.pid; then
        echo "Running"
    else
        echo "Not running"
    fi
Дима Л.
источник