- Linux / Unix команда, чтобы определить, запущен ли процесс?
- 12 ответов
- ВЫ ДОЛЖНЫ знать ПИД-код!
- Как определить, работает ли процесс (pid)
- Bash script — проверка программы на запущенность и ее запуск
- 32 комментария к записи “ Bash script — проверка программы на запущенность и ее запуск ”
- Запущен процесс или нет?
Linux / Unix команда, чтобы определить, запущен ли процесс?
Мне нужна независимая от платформы (Linux/Unix | OSX) оболочка /bash команда, которая определит, работает ли какой-либо конкретный процесс. например mysqld , httpd . Каков самый простой способ/команда для этого?
12 ответов
Хотя 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 '^[ ]*9*'
Выходные данные в Linux и OS X одинаковы:
Вывод следующего представляет собой пустую строку, что делает этот подход безопасным для процессов, которые не выполняются:
echo ps cax | grep aasdfasdf | grep -o '^[ ]*6*'
Этот подход подходит для написания простого теста пустой строки, а затем итерации через обнаруженные PID.
#!/bin/bash PROCESS=$1 PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*2*'` 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 для проверки возможного полного пути.
Процесс может быть запущен, но остановлен. Поэтому, если целью является проверка того, что mysqld или httpd «работают» (отвечает), вам также следует проверить, остановлен он или нет.
Извините, но, хотя ответ, конечно, правильный с семантической точки зрения, я полностью против попытки найти процесс путем сопоставления с образцом в векторе процесса arg. Любой такой подход рано или поздно обречен на провал (вы фактически признаете это сами, говоря, что нужно больше проверок). Я добавил свою рекомендацию в отдельный ответ.
grep также будет работать (например, ps cax | grep randomname всегда будет возвращать 0, потому что grep находит grep randomname (надеюсь, это понятно . ). Одним из исправлений является добавление квадратных скобок вокруг первой буквы имени процесса, например, ps cax | grep [r]andomname .
ps cax не может полностью выводить имя команды. Например, он печатает «хром-браузер» вместо «хром-браузер».
ВЫ ДОЛЖНЫ знать ПИД-код!
Поиск процесса путем попытки распознавания образов в аргументах процесса (например, pgrep «mysqld» ) — это стратегия, которая рано или поздно обречена на провал. Что делать, если у вас есть два mysqld? Забудьте о таком подходе. Вы МОЖЕТЕ исправить это временно, и МОЖЕТ РАБОТАть год или два, но потом что-то происходит, о чем вы не думали.
Идентификатор процесса (pid) действительно уникален.
Всегда сохраняйте pid, когда вы запускаете что-то в фоновом режиме. В Bash это можно сделать с помощью переменной $! Bash. Сделав это, вы сэкономите себя.
Как определить, работает ли процесс (pid)
Итак, теперь возникает вопрос, как узнать, работает ли pid.
Это POSIX и, следовательно, переносимый. Он вернет сам pid, если процесс запущен или ничего не возвращает, если процесс не запущен. Строго говоря, команда вернет один столбец pid , но так как мы указали на пустой заголовок заголовка (материал, непосредственно предшествующий знаку равенства), и это единственный запрашиваемый столбец, то команда ps не будет использовать заголовок вообще. Это то, что мы хотим, потому что оно упрощает синтаксический анализ.
Это будет работать на Linux, BSD, Solaris и т.д.
Другая стратегия — проверить значение выхода из вышеприведенной команды ps . Он должен быть равен нулю, если процесс запущен и не равен нулю, если это не так. Спецификация POSIX говорит, что ps должен выйти > 0, если произошла ошибка, но мне непонятно, что представляет собой «ошибка». Поэтому я лично не использую эту стратегию, хотя я уверен, что она будет работать и на всех платформах Unix/Linux.
За исключением того, что это не отвечает на вопрос, который должен определить, работает ли служба. PID не будет известно , в таких случаях, поэтому этот ответ действителен только , если вы знаете PID.
Неправильно. Весь мой смысл в комментарии заключается в том, чтобы сделать шаг назад и сказать, что если вы впервые оказались в ситуации, когда вам нужно выполнить какую-то форму grep
Более правильным «термином» для вопроса OP должен был быть «кроссплатформенная команда, чтобы определить, запущена ли служба», это не та же система, которая выполняет проверку, а внешняя система, поэтому PID просто не будет известен вообще.
То, будет ли известен PID, зависит от того, управляете ли вы процессом запуска или нет. Это не зависит от того, где вы делаете проверку. Вы можете реализовать свой собственный сервис is-service-running? (который использует сохраненный PID) на данном хосте, который затем может быть вызван с удаленного хоста. Но опять же: если вы не контролируете процесс запуска сервиса, тогда я понимаю вашу точку зрения.
Да, но сценарии не зависят друг от друга. Вот почему ps cax | grep
Как определить, работает ли процесс (по pid) именно то, что я искал. Я был удивлен, что все вопросы в моих результатах поиска были о том, как найти pid.
Это не надежно. Интересующий вас процесс мог умереть после того, как система проработала достаточно долго, чтобы обернуть PID, и тогда другому процессу мог быть назначен тот же PID, который вы проверяете. stackoverflow.com/questions/11323410/linux-pid-recycling
@claymation. Честная оценка. Однако метод PID все же лучше, чем сопоставление с образцом в аргументах процесса, поскольку конфликт PID гораздо менее вероятен, чем случайный запуск двух экземпляров одной и той же службы. Просто мои два цента. 🙂
В большинстве дистрибутивов Linux вы можете использовать pidof (8).
Он распечатает идентификаторы процессов всех запущенных экземпляров определенных процессов или ничего, если экземпляры не запущены.
Например, в моей системе (у меня есть четыре экземпляра bash и один экземпляр remmina ):
$ pidof bash remmina 6148 6147 6144 5603 21598
В других Unices, pgrep или комбинация ps и grep будут достигать того же, что и другие по праву отметили.
Bash script — проверка программы на запущенность и ее запуск
В общем, мне нужно было как-то примитивно проверить запущена ли программа, а если нет, то запустить её. Да, есть программы для мониторинга всего этого дела (например, mon), но ставить их из-за одной программы не хотелось, поэтому написал небольшой скрипт.
#!/bin/bash ret=$(ps aux | grep [h]top | wc -l) if [ "$ret" -eq 0 ] then < echo "Running Htop" #output text sleep 1 #delay htop #command for run program exit 1 >else < echo "EXIT. Htop already running!" exit 1 >fi;
Для начала смотрим запущена программа или нет:
ps aux выводит запущенные процессы.
grep [h]top выводит результаты с htop, при этом если первую букву процесса взять в квадратные скобки, то ‘grep htop’ будет исключаться из списка.
wc -l подсчитывает количество строк (запущенных процессов).
Выглядит это так:
total@total-MS-7638:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 86904 4460 ? Ss 16:04 0:00 /sbin/init root 2 0.0 0.0 0 0 ? S 16:04 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 16:04 0:00 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< 16:04 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S 16:04 0:00 [kworker/u:0] root 7 0.0 0.0 0 0 ? S< 16:04 0:00 [kworker/u:0H] root 8 0.0 0.0 0 0 ? S 16:04 0:00 [migration/0] root 9 0.0 0.0 0 0 ? S 16:04 0:00 [rcu_bh] syslog 1031 0.0 0.0 241120 1824 ? Sl 16:04 0:00 rsyslogd -c5 root 1045 0.0 0.0 83408 3280 ? Ss 16:04 0:00 /usr/sbin/modem-manager root 1047 0.0 0.0 19240 1792 ? Ss 16:04 0:00 /usr/sbin/bluetoothd root 1076 0.0 0.0 0 0 ? S< 16:04 0:00 [krfcommd] root 1149 0.0 0.2 179000 9384 ? Ss 16:04 0:00 /usr/sbin/cupsd -F root 1163 0.0 0.1 246044 5868 ? Ssl 16:04 0:00 NetworkManager root 1168 0.0 0.1 250220 6872 ? Sl 16:04 0:00 /usr/lib/policykit-1/polkitd --no-debug root 1170 0.0 0.0 10720 916 tty4 Ss+ 16:04 0:00 /sbin/getty -8 38400 tty4 root 1176 0.0 0.0 10720 920 tty5 Ss+ 16:04 0:00 /sbin/getty -8 38400 tty5 root 1182 0.0 0.0 10720 908 tty2 Ss+ 16:04 0:00 /sbin/getty -8 38400 tty2 root 1184 0.0 0.0 10720 916 tty3 Ss+ 16:04 0:00 /sbin/getty -8 38400 tty3 root 1186 0.0 0.0 10720 916 tty6 Ss+ 16:04 0:00 /sbin/getty -8 38400 tty6 root 1189 0.0 0.1 47312 4404 ? Ssl 16:04 0:01 /opt/teamviewer8/tv_bin/teamviewerd -f root 1214 0.0 0.0 4508 828 ? Ss 16:04 0:00 acpid -c /etc/acpi/events -s /var/run/acpid.socket daemon 1222 0.0 0.0 12792 136 ? Ss 16:04 0:00 atd root 1224 0.0 0.0 14992 980 ? Ss 16:04 0:00 cron root 1225 0.0 0.0 19148 728 ? Ss 16:04 0:00 /usr/sbin/irqbalance whoopsie 1234 0.0 0.1 282716 5044 ? Ssl 16:04 0:00 whoopsie openldap 1237 0.0 0.1 375504 6300 ? Ssl 16:04 0:00 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F colord 1266 0.0 0.1 210224 5444 ? Sl 16:04 0:00 /usr/lib/colord/colord root 1267 0.0 0.0 11876 840 ? Sl 16:04 0:00 /usr/sbin/pcscd root 1283 0.0 0.0 113448 1512 ? Ss 16:04 0:00 /usr/sbin/sensord -f daemon root 1296 0.0 0.0 124300 1948 ? S 16:04 0:00 smbd -F root 1311 0.0 0.0 0 0 ? S< 16:04 0:00 [iprt] root 1356 0.0 0.0 269148 3328 ? Ssl 16:04 0:00 lightdm root 1378 4.2 1.5 194792 60556 tty7 Ss+ 16:04 9:01 /usr/bin/X :0 -core -auth /var/run/lightdm/root/:0 -nolisten tcp total 3893 1.8 0.0 20752 2120 pts/1 S+ 19:35 0:00 htop total 3897 1.5 0.0 17496 3628 pts/2 Ss 19:35 0:00 bash total 3945 0.0 0.0 13352 1256 pts/2 R+ 19:35 0:00 ps aux total@total-MS-7638:~$ ps aux | grep htop total 3893 1.8 0.0 20752 2120 pts/1 S+ 19:35 0:00 htop total 3947 0.0 0.0 10684 952 pts/2 S+ 19:35 0:00 grep --color=auto htop total@total-MS-7638:~$ ps aux | grep [h]top total 3893 1.8 0.0 20752 2120 pts/1 S+ 19:35 0:00 htop total@total-MS-7638:~$ ps aux | grep [h]top | wc -l 1 total@total-MS-7638:~$ ps aux | grep htop | wc -l 2 total@total-MS-7638:~$
После этого нужно написать условие проверки и запуска программы.
if [ "$ret" -eq 0 ] - если ( if ) значение переменной (ключ -eq означает равно) равно 0, то ( then ):
echo "Running Htop" - выводим текст: "Запускается Htop";
sleep 1 - ставим задержку при запуске в 1 секунду;
htop - запускаем программу Htop;
exit 1 - выходим из скрипта;
Иначе ( else ):
echo "EXIT. Htop already running!" - выводим текст: "Htop уже запущен!"
exit 1 - выходим из скрипта.
Конструкция "Если. то. иначе. " обязательно заканчивается fi ;
Писать на Bash несложно, а также весьма увлекательно, в прочем, как и все в программировании. Так что попробуйте сами что-нибудь написать, у вас обязательно получится. Тем более, что по bash полно всякой документации, в том числе и на русском языке.
32 комментария к записи “ Bash script — проверка программы на запущенность и ее запуск ”
if [ "$ret" -eq 1 ] вот так работает с нулем всегда считает запущенным так как сама команда греп создает процесс и таким именем
Запущен процесс или нет?
Есть у меня пару bash и python скриптов, хочу сделать проверку запущенны они ли нет, если нет то запустить. Пробую ps -a в процессах показан запущенный скрипт. Пробую ps x | grep go.sh все работает. Закрываю терминал с нужным скриптом пробую снова ps x | grep go.sh снова выдает список процессов с go.sh. Почему это происходит? Как правильно отследить запущен процесс или нет?
Закрываю терминал с нужным скриптом пробую снова ps x | grep go.sh снова выдает список процессов.
Как правильно отследить запущен процесс или нет?
я думаю, что по pid'у будет надежнее.
Ошибся немного, исправил. А как по pid? По имени не всегда получится его получить.
по пид можно его сбросить прямо из шелл скрипта в pid файл (echo $$ /path/to/pid). потом читать из этого файла pid и делать дальше по ситуации (kill -0 $pid например, чтобы проверить, что он запущен).
чето вы тут фигней и велосипедами страдаете, есть же watch
Закрываю терминал с нужным скриптом пробую снова ps x | grep go.sh снова выдает список процессов с go.sh.
Не знаю как написан твой скрипт, он может игнорировать SIGHUP и не закрываться при закрытии терминала.
А ещё ps x | grep go.sh будет всегда что-нибудь выдавать, например сам процесс grep :)
$ ps x | grep этогодерьматочнонетвмоихпроцессах 6678 pts/0 S+ 0:00 grep этогодерьматочнонетвмоихпроцессах
Попробуй monit, как раз для этого предназначен.