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

Используя ex , POSIX заданные функции только
printf '%s\n' 0a '' . 1d 'g/pattern/-put | -,.!uniq' x | ex file

Краткое описание команд, переданных на ex ] от printf :

0a - append after line 0
   - an empty line
.  - stop appending
1d - delete line 1 (the new empty line) into the unnamed register (a.k.a. buffer)

g/pattern/-put | -,.!uniq

g/pattern/ - for every line in the file matching "pattern"
- - on the *previous* line,
put - "put" (linewise append) the contents of the unnamed register
| - and also do the following (still part of the g// command)
-,. - take the previous and current lines
!uniq - and run them through the external command "uniq"
        (replacing the lines with the output)

x - save changes and exit

ex стоит изучить. :)

11
14.01.2017, 20:56
3 ответа

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

ps ax  | grep -q [v]arnish

успешно, потому что запущен скрипт с именем check_ varnish _pro .

10
27.01.2020, 19:57

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

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

     varnish || истина 
    some_command_to_send_an_alert_that_the_service_has_died 
     
  • В качестве альтернативы измените сценарий, запускающий службу, на запись PID, , а затем периодически проверяйте состояние с помощью kill -0 "$ pid ".
4
27.01.2020, 19:57

В общем, пробовать простой подход с помощью 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 ( systemctl is-active --quiet varnish вернет 0, если он запущен, 3 в противном случае), в 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 , и вы получите нажмите на шаблон в таблице процессов (процесс grep ).

16
27.01.2020, 19:57

Теги

Похожие вопросы