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



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

854   14  

14 ответов:

пока 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

кроме того, если вы хотите список 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 работает? Забудьте об этом подходе. Вы можете получить это право временно, и это может работать в течение года или двух, но затем происходит что-то, о чем вы не думали.

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

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

как определить, если процесс выполняется (по pid)

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

просто:

ps -o pid= -p <pid>

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

это будет работать на Линукс, БСД, Солярис и т. д.

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

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

работает

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 release 4
  • Red Hat Enterprise Linux Server release 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

на основе ответ на peterh. Трюк для того, чтобы знать, если данный PID работает в 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. вырезать - просто разделить выводится разделителем ' / ' и извлекает поле 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 параметры и безвозмездно использует раковину, несмотря на свою популярность, не гарантируется присутствие на каждой машине Unix / Linux (bash)

Comments

    Ничего не найдено.