«Правильный» способ проверить, работает ли служба в скрипте

98

Моя проблема:

Я пишу сценарий bash, и в нем я хотел бы проверить, работает ли данный сервис.

Я знаю, как сделать это вручную, с $ service [service_name] status.

Но (особенно после перехода на systemd), который печатает целую кучу текста, который немного беспорядочно анализировать. Я предположил, что для скриптов с простым выводом сделана команда или возвращаемое значение, которое я могу проверить.

Но поиск в Google дает только массу результатов "О, просто ps aux | grep -v grep | grep [service_name]". Это не может быть лучшей практикой, не так ли? Что если запущен другой экземпляр этой команды, но не запущенный сценарием инициализации SysV?

Или мне просто заткнуться и испачкать руки маленьким пгрепом?

Ник С
источник

Ответы:

141

systemctlесть is-activeподкоманда для этого:

systemctl is-active --quiet service

выйдет со статусом ноль, если serviceактивен, ненулевой в противном случае, что делает его идеальным для сценариев:

systemctl is-active --quiet service && echo Service is running

Если вы опустите --quietего, он также выведет текущее состояние на стандартный вывод.

Как указывает don_crissti , некоторые юниты могут быть активными, даже если ничего не работает для предоставления сервиса: юниты, помеченные как «RemainAfterExit», считаются активными, если они успешно завершают свою работу, идея состоит в том, что они предоставляют сервис, который не нуждается в демоне. ( например, они настраивают какой-то аспект системы). Однако юниты с участием демонов будут активны, только если демон все еще работает.

Стивен Китт
источник
Осторожнее с услугами onehot. Они только inactiveили activatingи оба systemctl statusи systemctl is-activeвыходят с 3. (по состоянию на systemd-241 ) Обходной путь:systemctl show service | grep -qx ActiveStatus=activating
Алоис Махдал
@Alois Мне интересно, с какими сценариями вы сталкивались, когда вы хотели бы, чтобы сервис с одним снимком был активным; у тебя есть пример?
Стивен Китт
Конечно, @StephenKitt. Инструмент fooчто-то делает с системой, включая перезагрузку, и использует однократную службу, скажем, foo_cleanupпри следующей загрузке, чтобы очистить вещи. Я тестирую это (мой сценарий также запланирован как сервис) и хочу собирать ошибки впоследствии, но когда это позже (vsauce music)? Ну, один из критериев - это то, что foo_cleanupзакончил («перестал быть активным»).
Алоис Махдал
Возможно, стоит отметить, что «is-fail» также является опцией и полезна, если вам нужно выполнить действие, основанное на не запущенной службе.
Фил Хили
33

systemctlесть ли режим, подходящий для сценариев; используйте showвместо status, и добавьте параметры -p/ --propertiesи --value, чтобы получить только желаемый результат.

Вот пример (из системы Ubuntu 17.04):

$ systemctl show -p SubState --value NetworkManager
running

Бег (или иначе) это SubState. Если вы хотите узнать, активен ли сервис, используйте свойствоActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

Примечания от man:

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".
Занна
источник
2
+1 за сложный ответ. пожалуйста, укажите дистрибутив, который примет --versionопцию с systemctl.
СК Венкат
11

В дополнение к ответу Zanna, --valueопция systemctl showбыла введена в версии 230 systemd . Так что он может быть недоступен в некоторых дистрибутивах, таких как Debian Jessie.

В этом случае можно эмулировать опцию, используя sed:

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running
Oxmel
источник
1
+1 для указал на --value intro version & distro version, которая не будет работать.
СК Венкат
3

Я считаю это полезным для выполнения командной строки или если вы делаете сценарии.

Скопировано из @StephenKitt

Это проверит, не работает ли служба, и выполнит перезапуск службы.

systemctl is-active --quiet <service name> || <service name> restart

the ||there проверяет, является ли возвращаемое значение из systemctl ненулевым значением, если оно не активно, как объяснил автор.

звездочка
источник
Вы также можете использовать `is-failed 'для проверки необходимости перезагрузки. Это кажется немного более интуитивно понятным для перезапуска отказавшего сервиса.
Фил Хили
да, но для меня .. я хотел практиковать себя и предполагать, что все работает, когда это не так. так что я могу пойти проверить вещи с этим. просто если вы просто хотите проверить, не запущен ли он, тогда «is-failed» - это законный выбор. :)
звездочка
3


Я слишком поздно , чтобы партии, однако использование systemctl является активными вместе с &&и ||к этому в сценарии обыкновение быть дело все время. Ниже приведен пример, который я использовал для tomcat, но могу использовать его в методе, принимающем аргументы и передавая имя сервиса в качестве аргументов, если вам нужно проверить несколько сервисов, но это выходит за рамки данной области.

STATUS=`systemctl is-active tomcat.service`
  if [[ ${STATUS} == 'active' ]]; then
    echo "Execute your tasks ....."
  else 
    echo " Service not running.... so exiting "  
    exit 1  
  fi

Вот как я использовал .... Просто делюсь своим.

и для простоты и легких вещей следуйте за другими, объясненными здесь:

systemctl -q is-active tomcat.service  && echo "Tomcat Runnung" || echo "Service is not running at all "
САГАР Наир
источник
Как это лучше, чем просто if systemctl is-active --quiet tomcat.service? Кроме того, [[это не стандартная оболочка.
Тоби Спейт
@TobySpeight Вам нужно прочитать немного больше моего поста, как я уже упоминал в своем посте «Вот как я использовал… Просто делюсь своим». Я никогда не говорил, что это стандартная оболочка, если вы сделаете ее одной скобкой, она станет тогда, но это выходит за рамки этого. Кроме того, ниже я упоминаю простое использование одной строки, чтобы сделать это, используя &&и ||.
САГАР Наир
2

Вместо использования команды sed, как в ответе Oxmel, достаточно использовать cut -d'=' -f 2для всех запрашиваемых свойств:

например:

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running
Мохамед Эль
источник
Это здорово, но вам действительно нужно дать некоторые пояснения относительно того, что делают эти команды.
Фил Хили
-1

Только что нашли этот отличный маленький сценарий:

#!/bin/bash
service=replace_me_with_a_valid_service

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
  echo "$service is running!!!"
else
  /etc/init.d/$service start
fi

Источник

Терри
источник
Не у всех служб есть исполняемый файл с одинаковыми именами, и любой пользователь может запустить команду, которая случайно совпадет - это может привести к катастрофе.
Тоби Спейт