Почему у меня есть другой статус выхода для ps | grep в скрипте?

Я бегу ниже скрипта:

#!/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 

Случай похож на лак, который не установлен на сервере. Этот скрипт отлично работает на сервере, на котором установлен лак.

Зачем нужен другой статус выхода при запуске с использованием скрипта и командной строки? Как улучшить этот скрипт?

3 Solutions collect form web for “Почему у меня есть другой статус выхода для ps | grep в скрипте?”

Когда вы запускаете скрипт с именем check_varnish_pro.sh

 ps ax | grep -q [v]arnish 

является успешным, потому что есть скрипт с именем check_ лак _pro .

В общем, неплохо попробовать простой подход с ps и grep чтобы попытаться определить, работает ли данный процесс.

Вам было бы намного лучше использовать pgrep для этого:

 if pgrep "varnish" >/dev/null; then echo "Varnish in running" else echo "Varnish is not running" fi 

См. Руководство по pgrep . На некоторых системах (возможно, не на Linux) вы получаете флаг -q , соответствующий одному и тому же флагу для grep который избавляется от необходимости перенаправления на /dev/null . Существует также флаг -f который выполняет совпадение в полной командной строке, а не только имя процесса. Можно также ограничить соответствие процессам, принадлежащим конкретному пользователю, используя -u .

Установка pgrep также дает вам доступ к pkill который позволяет вам сигнализировать процессы на основе их имен.

Кроме того, если это демон службы , и если ваша система Unix имеет способ запросить его для получения информации (например, работает ли она или работает или нет), то это правильный способ проверки на ней. В Linux у вас есть systemctl (о котором я ничего не знаю), а на OpenBSD у вас есть rcctl , например.

Теперь к вашему сценарию:

В вашем скрипте вы разбираете вывод из ps ax . Этот вывод будет содержать имя самого скрипта, check_varnish_pro.sh , который, очевидно, содержит строковый varnish . Это дает вам ложный результат. Вы бы заметили это, если бы вы использовали его без флага -q для grep во время тестирования.

 #!/bin/bash ps ax | grep '[v]arnish' 

Запуск:

 $ ./check_varnish_pro.sh 31004 p1 SN+ 0:00.04 /bin/bash ./check_varnish_pro.sh 

Другая проблема заключается в том, что, хотя вы пытаетесь «скрыть» процесс grep от обнаружения самим grep , используя [v] в шаблоне. Этот подход потерпит неудачу, если вам удастся запустить сценарий или командную строку в каталоге, в котором есть файл или каталог с именем varnish (в этом случае вы снова получите ложный результат). Это связано с тем, что шаблон не кавыдается, и оболочка будет выполнять с ним имя файла.

Видеть:

 bash-4.4$ set -x bash-4.4$ ps ax | grep [v]arnish + ps ax + grep '[v]arnish' bash-4.4$ touch varnish + touch varnish bash-4.4$ ps ax | grep [v]arnish + ps ax + grep varnish 91829 p2 SN+p 0:00.02 grep varnish 

Наличие varnish файлов приведет к тому, что оболочка заменит [v]arnish на varnish filename и вы получите удар по шаблону в таблице процессов (процесс grep ).

@AlexP очень лаконично объясняет, что происходит на самом деле, но идея Kusalananda по использованию pgrep / pkill для критического процесса сильно обескуражена . Лучшие решения включают:

  • Спросить службу , работает ли она. systemctl status varnishd должен позаботиться об этом в современной установке * nix.
  • Если по каким-то неудачным обстоятельствам у вас нет доступной услуги, вы можете просто изменить сценарий запуска, чтобы сообщить о проблеме, как только процесс завершится:

     varnish || true some_command_to_send_an_alert_that_the_service_has_died 
  • В качестве альтернативы измените сценарий, который запускает службу для записи PID, а затем периодически проверяйте состояние с kill -0 "$pid" .
  • удалить строки в файле list_file из другого файла (ов)
  • Функция Zsh с su и echo
  • перебирать файлы и отправлять строки в качестве позиционных параметров в другой файл
  • Как суммировать определенные строки матрицы
  • Bash найти и заменить в файле C ++
  • Исправить файловую оболочку
  • Функция bash для обработки файла через symlink: проблема с аргументами командной строки
  • Изменение разрешений файла при использовании команды sftp в сценарии оболочки
  • Попытка сохранить вывод команды файла в переменную, но на выходе указано «нет такого файла существует»?
  • bash script «Нет такого файла ...»
  • Значение суммы рядом с определенным шаблоном
  • Linux и Unix - лучшая ОС в мире.