Команда Linux / Unix, чтобы определить, запущен ли процесс?
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
чтобы проверить полный путь, где это возможно.
ссылки:
вы должны знать 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
небольшое объяснение, что происходит:
- - m1-остановить процесс на первом матче
- "mysqld$ / httpd$" - grep будет соответствовать строкам, которые закончились на mysqld или httpd
- / proc / [0-9] * - bash будет соответствовать строке, которая началась с любого числа
- 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
)