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
стоит изучить. :)
Когда вы запускаете сценарий с именем check_varnish_pro.sh
, тест
ps ax | grep -q [v]arnish
успешно, потому что запущен скрипт с именем check_
varnish _pro
.
@AlexP очень кратко объясняет , что на самом деле происходит, но идея @Kusalananda использования pgrep
/ pkill
для критического процесса категорически не приветствуется. . Лучшие решения включают:
systemctl status varnishd
должен позаботиться об этом в современной установке * nix. Если по каким-то неблагоприятным обстоятельствам у вас нет доступной службы, вы можете просто изменить сценарий запуска, чтобы сообщить о проблеме, как только процесс завершится:
varnish || истина
some_command_to_send_an_alert_that_the_service_has_died
kill -0 "$ pid "
. В общем, пробовать простой подход с помощью 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
).