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

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

14 ответов


пока pidof и pgrep являются отличными инструментами для определения того, что работает, они оба, к сожалению, недоступны в некоторых операционных системах. Определенный fail safe был бы использовать следующее: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

кроме того, если вы хотите список PIDs, вы можете легко 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]*'

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

#!/bin/bash
PROCESS=
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


вы должны знать PID !

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

only the process id (pid) поистине уникально.

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

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

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

просто:

ps -o pid= -p <pid>

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

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

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


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

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

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

$ pidof bash remmina
6148 6147 6144 5603 21598

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


самый простой способ-использовать 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 с аргументом:

-Джава.утиль.лесозаготовительный.конфиг.file=ведение журнала.свойства

работает

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l

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

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

ps acux | grep cron

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

о системе, где генетика родного ps командная точка обратно в SysV, вы бы использовали

ps -e |grep cron

или

ps -el |grep cron 

для a список, содержащий больше, чем просто pid и имя процесса. Конечно, вы можете выбрать конкретные поля для печати с помощью .


собирая различные предложения вместе, самая чистая версия, которую я смог придумать (без ненадежного 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"

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


вы должны знать 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

на основе ответ of peterh. Трюк для зная, если данный ПИД работает в ps -o pid= -p $PID инструкция.


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

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

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

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

это выводит количество процессов, базовым именем которых является "chromium-browser":

ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match(,/^\[.*\]$/)){sub(".*/","",)} # Do not strip process names enclosed by square brackets.
 if(==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=
 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 }}
}END{exit status}' cmd="" 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"

вот моя версия. Особенности:

  • проверяет точное имя программы (Первый аргумент функции). поиск " mysql "не будет соответствовать запуску"mysqld"
  • поиск аргументов программы (второй аргумент функции)

сценарий:

#!/bin/bash

#  - cmd
#  - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
    for i in $(pidof ); do
        cat /proc/$i/cmdline | tr '0' ' ' | grep -F -e "" 1>&2> /dev/null
        if [ $? -eq 0 ]; then
            return 0
        fi
    done
    return 1
}

isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
    echo "not running, starting..."
fi

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

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

объяснение:

|tr -d '\n'

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


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

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk ' ~ "^.*/'""'$" ||  ~ "^'""'$" {print ,}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "" "$cmd" ||
    printf "%s is not running\n\n" 
  [ -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 options и безвозмездно использует оболочку, которая, несмотря на свою популярность, не гарантируется присутствие на каждой машине Unix / Linux (bash)