Я бегу ниже сценария:
#!/bin/bash
ps ax | grep -q [v]arnish
if [ $? -eq 0 ];then
echo varnish is running...
exit 0
else
echo "Critical : varnish is not running "
exit 2
fi
Выход похож на ::
[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0
Когда я запускаю то же самое в командной строке, я получаю статус выхода как 1:
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
Дело в том, что лак не установлен на сервере. Этот скрипт отлично работает на сервере, где установлен лак.
Почему разные состояния выхода при запуске с использованием скрипта и командной строки? Как улучшить этот скрипт?
shell-script
process
ps
exit-status
Prado
источник
источник
Ответы:
Когда вы запускаете скрипт с именем
check_varnish_pro.sh
тестауспешно, потому что есть скрипт с именем
check_
varnish_pro
.источник
В общем, плохая идея попробовать простой подход
ps
иgrep
попытаться определить, запущен ли данный процесс.Вам было бы гораздо лучше использовать
pgrep
для этого:Смотрите руководство для
pgrep
. В некоторых системах (возможно, не в Linux) вы получаете-q
флаг, соответствующий тому же флагу, дляgrep
которого избавляется от необходимости перенаправления/dev/null
. Также есть-f
флаг, который выполняет сопоставление в полной командной строке, а не только в имени процесса. Можно также ограничить соответствие процессами, принадлежащими конкретному пользователю, использующему-u
.Установка
pgrep
также дает вам доступ кpkill
которому позволяет сигнализировать о процессах на основе их имен.Кроме того, если это демон службы , и если ваша система Unix имеет способ запрашивать у него информацию (например, работает ли она или нет), тогда это правильный способ проверки.
В Linux у вас есть
systemctl
(systemctl is-active --quiet varnish
вернет 0, если он работает, 3 в противном случае), в OpenBSD у вас естьrcctl
и т. Д.Теперь к вашему сценарию:
В вашем скрипте вы анализируете вывод из
ps ax
. Этот вывод будет содержать имя самого скриптаcheck_varnish_pro.sh
, который, очевидно, содержит строкуvarnish
. Это дает вам ложный положительный результат. Вы бы заметили это, если бы тестировали его без-q
флагаgrep
.Запуск это:
Другая проблема заключается в том, что, хотя вы пытаетесь «спрятать»
grep
процесс от его обнаруженияgrep
, используя[v]
шаблон. Этот подход потерпит неудачу, если вам случится запустить скрипт или командную строку в каталоге, в котором указан файл или каталогvarnish
(в этом случае вы снова получите ложное срабатывание). Это связано с тем, что шаблон не заключен в кавычки и оболочка будет выполнять с ним поиск по имени файла.Видеть:
Наличие файла
varnish
приведет к тому, что оболочка заменит[v]arnish
имя файла,varnish
и вы получите удар по шаблону в таблице процессов (grep
процесс).источник
check_varnish_pro.sh
также является фактором.@AlexP очень кратко объясняет, что происходит на самом деле, но идея @ Kusalananda использовать
pgrep
/pkill
для критического процесса настоятельно не рекомендуется . Лучшие решения включают в себя:systemctl status varnishd
следует позаботиться об этом на современной установке * nix.Если по каким-то непредвиденным обстоятельствам у вас нет доступной службы, вы можете просто изменить сценарий запуска, чтобы сообщить о проблеме, как только процесс завершится:
kill -0 "$pid"
.источник
systemctl
это доступно почти только в Linux (AFAIK), и не во всех современных Unix-подобных системах.