Linux/Unix, чтобы определить, запущен ли процесс?

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

Ответ 1

Хотя 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, вы можете легко grep для них:

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

Выходные данные в Linux и OS X одинаковы:

3519 3521 3523 3524

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

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

Этот подход подходит для написания простого теста пустой строки, а затем итерации через обнаруженные 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

Ответ 2

ВЫ ДОЛЖНЫ знать ПИД-код!

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

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

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

Как определить, работает ли процесс (pid)

Итак, теперь возникает вопрос, как узнать, работает ли pid.

Просто выполните:

ps -o pid= -p <pid>

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

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

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

Ответ 3

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

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

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

$ pidof bash remmina
6148 6147 6144 5603 21598

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

Ответ 4

Это должно работать на большинстве вариантов 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)
  • Дарвин 11.2.0
  • FreeBSD 9.0-STABLE
  • Red Hat Enterprise Linux ES release 4
  • Red Hat Enterprise Linux Server выпуска 5

Ответ 5

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

ps acux | grep cron

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

В системе, где генетика команды native ps указывает на SysV, вы должны использовать

ps -e |grep cron

или

ps -el |grep cron 

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

Ответ 6

Самый простой способ - использовать 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

Ответ 7

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

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

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

$ mysql &
$ echo $! > pid_stored

затем в script:

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

Ответ 8

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

Ответ 9

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

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

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

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.

Ответ 10

Этот подход может быть использован в случаях, когда команды "ps", "pidof" и "rest" недоступны. Я лично использую procfs очень часто в своих инструментах/сценариях/программах.

   egrep -m1  "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3

Маленькое объяснение, что происходит:

  • -m1 - остановить процесс при первом совпадении
  • "mysqld $| httpd $" - grep будет соответствовать строкам, которые закончились на mysqld ИЛИ httpd
  • /proc/[0-9] * - bash будет соответствовать строке, которая начиналась с любого числа
  • cut - просто разделите результат на разделитель '/' и поле для извлечения 3

Ответ 11

Отправляет количество процессов, чье базовое имя - "хром-браузер":

ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
 if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"

Если это печатает "0", процесс не выполняется. Команда предполагает, что путь процесса не содержит разрывного пространства. Я не тестировал это с приостановленными процессами или процессами зомби.

Протестировано с использованием gwak в качестве альтернативы awk в Linux.

Вот более универсальное решение с некоторыми примерами использования:

#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
 local quiet=1;
 shift
else
 local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
 name=$2
 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
 if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}

process='chromium-browser'

printf "Process \"${process}\" is "
if isProcessRunning -q "$process" 
 then printf "running.\n"
 else printf "not running.\n"; fi

printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"

Ответ 12

Следующая функция оболочки, основанная только на стандартных командах и параметрах POSIX, должна работать на большинстве (если не на всех) Unix и Linux-системах.

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "$1" "$cmd" ||
    printf "%s is not running\n\n" $1
  [ -n "$cmd" ]
}

$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd

$ isPidRunning ksh
ksh is running
5230 ksh

$ isPidRunning bash
bash is not running

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

Отметим также, что для большинства приоритетных и принятых решений требуются не переносимые опции ps, и безвозмездно использует оболочку, которая, несмотря на свою популярность, не гарантируется на всех машинах Unix/Linux (bash)