"Правильний" спосіб перевірити, чи працює служба в сценарії


96

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

Я пишу bash-скрипт, і в ньому я хотів би перевірити, чи працює ця послуга.

Я знаю, як це зробити вручну, за допомогою $ service [service_name] status.

Але (особливо з моменту переходу на systemd), який друкує цілу купу тексту, яка трохи заплутана для розбору. Я припускав, що є команда, створена для сценаріїв з простим висновком або зворотним значенням, яке я можу перевірити.

Але гугл навколо дає лише тону результатів "О, просто ps aux | grep -v grep | grep [service_name]". Це не може бути найкращою практикою, чи не так? Що робити, якщо інший екземпляр цієї команди запущений, але не один, запущений скриптом init SysV?

Або я повинен просто заткнутись і забруднити руки маленькою шкрепкою?

Відповіді:


139

systemctlis-activeдля цього є підкоманда:

systemctl is-active --quiet service

вийде з нульовим статусом, якщо serviceвін активний, а не нульовим інакше, що робить його ідеальним для сценаріїв:

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

Якщо ви відмовитесь, --quietвін також виведе поточний стан на його стандартний вихід.

Як зазначає don_crissti , деякі блоки можуть бути активними, навіть якщо для надання послуги нічого не працює: блоки, позначені як "RemainAfterExit", вважаються активними, якщо вони успішно виходять, ідея полягає в тому, що вони надають послугу, яка не потребує демон ( наприклад, вони налаштовують певний аспект системи). Однак одиниці з участю демонів будуть активними лише у тому випадку, коли демон все ще працює.


Будьте уважні до тих, хто користується послугами. Вони є лише inactiveабо activatingі тим, systemctl statusі systemctl is-activesystemctl show service | grep -qx ActiveStatus=activating
іншим

@Alois Мені цікаво, з якими сценаріями ви стикалися, де хочете вважати послугу onehot активною; у вас є приклад?
Стівен Кітт

Звичайно, @StephenKitt. Інструмент fooробить щось із системи, що включає перезавантаження, і використовує службу з одним знімком, скажімо, foo_cleanupпри наступному завантаженні для очищення речей. Я перевіряю це (мій сценарій також запланований як сервіс) і хоче , щоб збирати помилки потім, але коли це потім (Vsauce музики)? Ну один із критеріїв - це те, що foo_cleanupзакінчено ("перестала бути активною").
Алоїз Магдал

Можливо, варто зазначити, що "невдало" також є варіантом, і це корисно, якщо вам потрібно виконати дію на основі не запущеної послуги.
Філл Хелі

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

Як доповнення до відповіді Занні, --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

1
+1 для вказаної - варті інтро-версії та дистрибутива, які не працюватимуть.
СК Венкат

3

я вважаю це корисним для виконання командного рядка або якщо ви робите сценарії.

Скопійовано з @StephenKitt

Це дозволить перевірити, чи не працює служба, і виконати перезапуск служби

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

||там перевіряє повертається значення systemctl ненульового значення , якщо він не активний , як описаний автором.


Ви також можете використати тест "is-fail", щоб перевірити, чи потрібен перезапуск. Це здається трохи більш інтуїтивним для перезавантаження невдалої послуги.
Філл Хелі

так, але для мене .. Я хотів попрактикуватись і припустити, що все працює, коли це не так. тож я можу переглядати речі, перевіряючи інші речі. просто якщо ви просто хочете перевірити, чи не працює він, то "є-невдало" - це правильний вибір. :)
зірочка

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? Крім того, [[це не стандартна оболонка.
Toby Speight

@TobySpeight Вам потрібно прочитати мій пост трохи більше, як я вже згадував у своєму дописі "Ось як я скористався .... Просто поділився моїм". Я ніколи не говорив, що це стандартне використання оболонки, якщо ти зробиш його єдиною дужкою, це стане тоді, але це не виходить тут. Крім того, я нижче згадую просте використання однієї лінії, щоб зробити це за допомогою &&та ||.
SAGAR Nair

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

Джерело


Не у всіх службах є виконаний файл з однаковою назвою, і будь-який користувач може запустити команду, яка випадково відповідає - це рецепт катастрофи.
Toby Speight
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.