Команда Linux / Unix, чтобы определить, запущен ли процесс? - PullRequest
90 голосов
/ 02 февраля 2012

Мне нужна не зависящая от платформы (Linux / Unix | OSX) команда shell / bash, которая определит, запущен ли конкретный процесс.например, mysqld, httpd ... Какой самый простой способ / команда для этого?

Ответы [ 14 ]

160 голосов
/ 02 февраля 2012

Хотя pidof и pgrep являются отличными инструментами для определения того, что работает, они, к сожалению, недоступны в некоторых операционных системах. Определенный отказоустойчивый будет использовать следующее: ps cax | grep command

Вывод в Gentoo Linux:

14484 ?        S      0:00 apache2
14667 ?        S      0:00 apache2
19620 ?        Sl     0:00 apache2
21132 ?        Ss     0:04 apache2

Выход на OS X:

42582   ??  Z      0:00.00 (smbclient)
46529   ??  Z      0:00.00 (smbclient)
46539   ??  Z      0:00.00 (smbclient)
46547   ??  Z      0:00.00 (smbclient)
46586   ??  Z      0:00.00 (smbclient)
46594   ??  Z      0:00.00 (smbclient)

Как в Linux, так и в OS X, grep возвращает код завершения, поэтому легко проверить, был ли найден процесс:

#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

Кроме того, если вам нужен список идентификаторов PID, вы также можете легко их найти:

ps cax | grep httpd | grep -o '^[ ]*[0-9]*'

Чей вывод одинаков в Linux и OS X:

3519 3521 3523 3524

Вывод следующего является пустой строкой, что делает этот подход безопасным для процессов, которые не запущены:

echo <code>ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'</code>

Этот подход подходит для написания простого теста пустой строки, а затем итерации по обнаруженным идентификаторам PID.

#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
  echo "Process not running." 1>&2
  exit 1
else
  for PID in $PIDS; do
    echo $PID
  done
fi

Вы можете проверить это, сохранив его в файл (с именем «running») с разрешениями на выполнение (chmod + x running) и выполнив его с параметром: ./running "httpd"

#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

ВНИМАНИЕ !!!

Имейте в виду, что вы просто анализируете вывод ps ax, что означает, что, как видно из вывода Linux, он не просто совпадает с процессами, но и с аргументами, переданными этой программе. Я настоятельно рекомендую при использовании этого метода быть как можно более точным (например, ./running "mysql" также будет соответствовать процессам mysqld). Я настоятельно рекомендую использовать which для проверки полного пути, где это возможно.


Ссылка:

http://linux.about.com/od/commands/l/blcmdl1_ps.htm

http://linux.about.com/od/commands/l/blcmdl1_grep.htm

24 голосов
/ 14 февраля 2013

Вы ДОЛЖНЫ знать PID!

Нахождение процесса путем попытки какого-либо распознавания образов по аргументам процесса (например, pgrep "mysqld") - это стратегия, которая рано или поздно обречена на неудачу.Что делать, если у вас работает два mysqld?Забудь о таком подходе.Вы МОЖЕТЕ сделать это правильно временно, и МОЖЕТ работать в течение года или двух, но затем происходит что-то, о чем вы не задумывались.

Только идентификатор процесса (pid) действительно уникален.

Всегда сохраняйте pid при запуске чего-либо в фоновом режиме.В Bash это можно сделать с помощью переменной $! Bash.Таким образом вы избавите себя от больших трудностей.

Как определить, запущен ли процесс (по pid)

Так что теперь возникает вопрос, как узнать, запущен ли pid.

Просто сделайте:

ps -o pid= -p <pid>

Это POSIX и, следовательно, переносимый.Он вернет сам pid, если процесс запущен, или ничего не вернет, если процесс не запущен.Строго говоря, команда вернет один столбец, pid, но, поскольку мы дали пустой заголовок заголовка (материал, непосредственно предшествующий знаку равенства), и это единственный запрошенный столбец, команда ps не будет использовать заголовоксовсем.Это то, что мы хотим, потому что это облегчает анализ.

Это будет работать в Linux, BSD, Solaris и т. Д.

Другая стратегия состояла бы в проверке значения выхода из приведенного выше * 1023.* команда.Он должен быть нулевым, если процесс запущен, и ненулевым, если это не так.Спецификация POSIX говорит, что ps должен выйти> 0, если произошла ошибка, но мне неясно, что представляет собой «ошибка».Поэтому я лично не использую эту стратегию, хотя я почти уверен, что она будет работать на всех платформах Unix / Linux.

14 голосов
/ 02 февраля 2012

В большинстве дистрибутивов Linux вы можете использовать pidof (8).

Он будет печатать идентификаторы всех запущенных экземпляров указанных процессов или ничего, если нет запущенных экземпляров.

Например, в моей системе (у меня работает четыре экземпляра bash и один экземпляр remmina):

$ pidof bash remmina
6148 6147 6144 5603 21598

В других Юнитах pgrep или комбинация ps и grep достигнет того же, что справедливо указали другие.

6 голосов
/ 26 октября 2012

Самый простой способ - использовать ps и grep:

command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
    echo "Command is running"
else
    echo "Command is not running"
fi

Если у вашей команды есть некоторые командные аргументы, вы также можете поставить больше 'grep cmd_arg1' после 'grep $ command', чтобы отфильтровать другие возможные процессы, которые вас не интересуют.

Пример: показать мне, если какой-либо процесс Java с предоставленным аргументом:

-Djava.util.logging.config.file = logging.properties

работает

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l
6 голосов
/ 02 февраля 2012

Это должно работать на большинстве разновидностей Unix, BSD и Linux:

PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep

Проверено на:

  • SunOS 5.10 [Следовательно, PATH=...]
  • Linux 2.6.32 (CentOS)
  • Linux 3.0.0 (Ubuntu)
  • Darwin 11.2.0
  • FreeBSD 9.0-STABLE
  • Red HatEnterprise Linux ES выпуск 4
  • Red Hat Enterprise Linux Server выпуск 5
5 голосов
/ 04 апреля 2014

Объединяя различные предложения, самая чистая версия, которую я смог придумать (без ненадежного grep, который запускает части слов):

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

kill -0 не убивает процесс, но проверяет, существует ли он, а затем возвращает true, если в вашей системе нет pidof, сохраните pid при запуске процесса:

$ mysql &
$ echo $! > pid_stored

затем в сценарии:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
5 голосов
/ 03 февраля 2012

Просто незначительное добавление: если вы добавите флаг -c в ps, вам не нужно удалять строку, содержащую процесс grep с grep -v впоследствии. * Т.е. 1003 *

ps acux | grep cron

- это все, что нужно для печати в системе bsd-ish (включая MacOSX). Вы можете оставить -u, если вам нужно меньше информации.

В системе, где генетика нативной командной строки ps возвращается к SysV, вы должны использовать

ps -e |grep cron

или

ps -el |grep cron 

для списка, содержащего не только pid и имя процесса. Конечно, вы можете выбрать конкретные поля для печати, используя опцию -o <field,field,...>.

3 голосов
/ 02 февраля 2012

Я использую pgrep -l httpd, но не уверен, что он присутствует на любой платформе ...
Кто может подтвердить на OSX?

1 голос
/ 15 ноября 2016

Вы должны знать PID вашего процесса.

Когда вы запустите его, его PID будет записан в переменную $!.Сохраните этот PID в файл.

Затем вам нужно будет проверить, соответствует ли этот PID запущенному процессу.Вот полный скелетный скрипт:

FILE="/tmp/myapp.pid"

if [ -f $FILE ];
then
   PID=$(cat $FILE)
else
   PID=1
fi

ps -o pid= -p $PID
if [ $? -eq 0 ]; then
  echo "Process already running."  
else
  echo "Starting process."
  run_my_app &
  echo $! > $FILE
fi

На основе ответа из peterh.Хитрость в том, чтобы знать, работает ли данный PID, заключается в инструкции ps -o pid= -p $PID.

0 голосов
/ 20 июня 2018

Ни один из ответов не сработал для меня, поэтому вот мой:

process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
  echo "Process is not running."
else
  echo "Process is running."
fi

Пояснение:

|tr -d '\n'

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...