В общем, мне нужно было как-то примитивно проверить запущена ли программа, а если нет, то запустить её. Да, есть программы для мониторинга всего этого дела (например, 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 | wc -l
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 полно всякой документации, в том числе и на русском языке.
if [ "$ret" -eq 1 ]
вот так работает с нулем всегда считает запущенным так как сама команда греп создает процесс и таким именемВ пояснении к скрипту написано, как исключается из списка процессов сам grep.
Не спорю возможно 🙂 но моя убунта 14.04 упорно считала сама себя 🙂
Это странно.
Что у Вас выводит эта команда?
Походу ничего не выводит, скобки не воспринимает. Это урезанная pxe сборка для загрузки по nfs. А вот на основном серве с полноценной инсталяшкой все работает для интересу проверил.
Если htop не запущен, команда и не должна ничего выводить. Скобки служат для исключения grep из вывода.
Скорее всего, grep у Вас работает как раз верно, не смотря на сборку.
Чё-то как-то сложновато у вас всё. Вот как я сделал бы:
Проверено на труъ убунте в bash и sh.
А
ps aux | grep [t]op
выдаёт лично у меня нечто со словами org.freedesktop.Это, конечно, top, а не htop… Но зачем такое писать? Какие-то квадратные скобки… То ли выпендрёж, то ли костыли… Тем более с aux зачем-то… Зачем? Почему не -a, не -d, а именно aux? Не понимаю…
Мало ли что там у человека запущено с таким сочетанием букв в путях, именах или параметрах… Вы бы ещё «e» в опции добавили для пущего веселья.
Спасибо за полезный комментарий!
Однако, справедливости ради замечу, что когда ты админишь сервера, то посмотреть вывод ps намного проще и быстрее, чем городить конструкции из if-условий 🙂 В скрипте, согласен, так выглядит элегантнее.
До debian 10.5 работало отлично. На debian 10.5 такая конструкция у меня сломалась, в итоге нагенерировалось максимальное число (4915) процессов cron и все cron-скрипты встали с ошибкой «(CRON) error (can’t fork)» в syslog.
В 10.6 также не работает, поэтому я просто написал юнит для systemd для своего python-скрипта, чтобы автоматом перезапускался, если вдруг упадет.
Чтобы не считать вывод самой grep можно сделать так — ps ax | grep -v grep | grep ‘имя’
Привет из 2к20, немного отредачил скрипт, мне кажется более правильна такая конструкция. Привет работы сквида.
1) Вы проверяете сервис, а не процесс. Не каждый процесс — это сервис.
2) Будет работать для systemd, но не для SysVinit.
Ребятки, идея хорошая конечно, но есть иной способ -> в /etc/crontab добавить строку
описание строки ->
Ежеминутно, с 10 до 18, с Пн по Пт, от имени zerg, проверять из запущенных процессов наличие запуска eog и если он не найден то запустить на дисплее :0 программу eog в полноэкранном режиме, именно определённый файл /ARH/RIP/01.jpg .
Это что за дичь, а главное как это относится к топику?
название какое? «проверка программы на запущенность и ее запуск»
программу проверит на запущенность крон, и если не запущена (рухнула по какой-то причине) то стартанет заново.
в моём примере представлен запуск (на случай падения) трансляции картинок в слайдшоу на рекламном мониторе. по такой же аналогии можно запускать или выключать процессы на своё усмотрение и не ломать голову с громоздкими скриптами .
вспомни что это и поймёшь как применить->
&&
;
||
О, теперь хоть цель скрипта стала ясна. Из первого комментария вообще не очевидно, для каких целей предложено использовать крон и запуск eog.
Привет, а подскажи, как сделать, чтобы приходили уведомления на почту, если вдруг выяснилось,что службу приходилось перезапустить?
Например,
Здравствуйте. Как прописать все тоже самое, только не для запуска дисплея, а для запуска процесса?
На что только не идут люди лишь бы не использовать pidof.
Так интереснее
Как сделать, чтобы этот скрипт отрабаотывал раз, к примеру, в 5 секунд?
Убрать выход из условия, обернуть в цикл и выставить sleep 5.
А как же Cron?)
а никак, это просто один из способов. какой тебе удобен тем и пользуйся.
cron позволяет выполнять проверки минимум раз в минуту. Можно еще заморочиться с incrontab, но проще через sleep в цикле запустить.
В отличии от Cron, скрипт запускает процесс один раз — только при старте системы? То есть если во время работы процесс упадет, то скрипт его не запустит?
Для этих целей существуют службы.
У меня получилось реализовать данную задачу без скрипта, как парень выше показал с дисплеем.
Я добавил в /etc/crontab следующую строку:
*/1 * * * * root ps -A | grep xxx > /dev/null || /etc/init.d/xxx start
где xxx — имя программы
Так же после grep xxx я прописал > /dev/null, чтобы каждую минуту после проверки процесса xxx на запущенность не создавалось новое письмо в файле /var/spool/mail/root и не выдавалось об этом сообщение в терминале.
Принцип работы команды я понял, но на всякий случай хотелось бы у вас уточнить какое условие выполняет данный символ ||, так как я в этом вообще не разбираюсь.
Как я понимаю, он выполняет следующее условие — если процесс xxx не найден, то выполнить команду /etc/init.d/xxx start, правильно я понимаю? И правильно ли я сделал остальное? Пока все работает, но спрашиваю ваше мнение на случай возможных проблем из-за возможной ошибки.
Да,
||
— логическое «или», то есть ищем процесс, «иначе» (если не нашли) запускаем его.a && b
— если выполнилось a, нужно выполнить ba || b
— если a не выполнилось, выполнить b