Мне нужна независимая от платформы (Linux/Unix | OSX) оболочка /bash команда, которая определит, работает ли какой-либо конкретный процесс. например mysqld
, httpd
...
Каков самый простой способ/команда для этого?
Linux/Unix, чтобы определить, запущен ли процесс?
Ответ 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
для проверки возможного полного пути.
Литература:
Ответ 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
)