"Правильний" спосіб запустити скрипт оболонки як демон


20

Я пишу сценарій оболонки, який хотів би запустити як демон при запуску, не використовуючи зовнішніх інструментів, таких як daemontools або daemonize .


Linux Daemon Writing HOWTO

За версією Linux Daemon Writing HOWTO , належний демон має такі характеристики:

  • вилки з батьківського процесу
  • закриває всі дескриптори файлів (тобтоstdin , stdout, stderr)
  • відкривається журнали для запису (якщо налаштовано)
  • змінює робочий каталог на стійкий (зазвичай /)
  • скидає маску режиму файлу (umask)
  • створює унікальний ідентифікатор сесії (SID)

Демонізувати Вступ

демон Введення йде далі, стверджуючи , що типовий демон також:

  • відключається від свого терміналу управління (якщо такий є) і ігнорує всі сигнали терміналу
  • розлучається зі своєю групою процесів
  • ручки SIGCLD

Як би зробити все це в sh, dashабо bashсценарій тільки з загальними інструментами Linux?

Сценарій повинен мати можливість працювати на якомога більше дистрибутивах без додаткового програмного забезпечення, хоча Debian є нашим основним напрямком.


ПРИМІТКА. Я знаю, що в мережі StackExchange є багато відповідей, що рекомендують використовувати nohupабо setsid, але жоден із цих методів не вирішує всіх вищезазначених вимог.


EDIT: Сторінка демона (7) також дає деякі вказівки, хоча, мабуть, є деякі відмінності між SysVдемонами старого стилю та новими systemd. Оскільки сумісність із різноманітними дистрибутивами є важливою, будь ласка, переконайтеся, що відповідь чітко визначає будь-які відмінності.



1
«Правильний» спосіб виробити свій власний скрипт, щоб зробити це зробити свій власний протоколювання, забезпечити спосіб його запуску в якості демона і т.д. Такі речі , як daemonі ті , і інші речі для запуску довільних скриптів, без надання для роботи в якості демон. Оскільки ви автор, повністю керуючи тим, як написаний цей скрипт, зробіть його таким, щоб його можна було просто запустити із системного unitfile або rc.d сценарію. Ви ж вказати «Правильні»!
Багатий

Відповіді:


16

Використовуючи systemd, ви повинні мати можливість запустити сценарій як демон, створивши простий блок. Ви можете додати багато різних варіантів, але це приблизно так просто, як ви можете отримати.

Скажіть, у вас є сценарій /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Ви створюєте підрозділ /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

Для запуску демона ви біжите

systemctl start mydaemon.service 

Щоб почати з завантаження, ви це вмикаєте

systemctl enable mydaemon.service

Якщо на систематизованій системі, яка сьогодні є більшістю дистрибутивів Linux, це насправді не є зовнішнім інструментом. Негативом було б те, що воно не працюватиме всюди.


3
Хоча мені подобається системний підхід, ОП заявила, що "немає зовнішніх інструментів". Є дистрибутиви Linux, які ще не мають системи, або дозволяють вам вибирати між systemd та чимось іншим, наприклад, OpenRC.
Крістіан Цюпіту

5
Для дистрибутивів, які використовують systemd, systemdце не більше "зовнішній інструмент", ніж bash.
Олександр

7

Я, мабуть, щось тут пропускаю; чому точно не nohupбуло б доречно? Звичайно, це недостатньо поодинці , але доповнення здається простим.

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add nice and ionice before nohup but they might not be installed
nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

Наскільки я бачу:

  • висновок відповідним чином переспрямований (при необхідності використовувати / dev / null)
  • umask передається у спадок
  • stdin вмирає в кінці батьківського сценарію
  • сценарій daemon.sh буде відновлено до init(або systemd)

У мене є сильне почуття, я пропускаю очевидне. Downvote, але скажіть, будь ласка, що це :-)


2
Я збирався запропонувати щось дуже схоже. Я використовую за nohupдопомогою &перенаправлення вводу / виводу для запуску декількох Cнедемонових утиліт, можливо, додаткова безпека загортання вашої nohupкоманди всередині a, su -c "nohup ... &" -s /bin/bash systemUserщоб запустити демон як непривілейований користувач.
111 ---

4

Команда Linux, що screenміститься в більшості дистрибутивів, може демонструвати сценарій оболонки. Я цим часто користуюся. Ось короткий приклад для запуску, списку та виходу з окремого сеансу на екрані ...

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit

2
screenне деамонізує сценарій оболонки. Він просто запустить їх у відмінний термінал і може відключитися від цього терміналу (як-от відключити клавіатуру від ПК) без закриття сесії. Отже, програма, що працює в окремому терміналі, працює у фоновому режимі. Тому - від'єднайте програму пропуску у фоновому режимі.
Юрій Гончарук
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.