Sistemli, interaktiv skriptlər və taymerlər

Sistemli, interaktiv skriptlər və taymerlər

Giriş

Linux üçün inkişaf etdirərkən, sistem açıldıqda və ya bağlandıqda yerinə yetirilən interaktiv skriptlərin yaradılması vəzifəsi yaranır. Sistem V-də bu asan idi, lakin systemd ilə düzəlişlər edir. Lakin onun öz taymerləri ola bilər.

Niyə bizə hədəflər lazımdır?

Çox vaxt hədəfin V -init sistemində işləmə səviyyəsinin analoqu kimi xidmət etdiyi yazılır. Mən kökündən razı deyiləm. Onlardan daha çoxu var və paketləri qruplara bölmək və məsələn, bir komanda ilə xidmətlər qrupunu işə salmaq və əlavə hərəkətlər etmək olar. Üstəlik, onların iyerarxiyası yoxdur, yalnız asılılıqları var.

Çalışan interaktiv skript ilə aktivləşdirildikdə hədəf nümunəsi (xüsusiyyətə baxış).

Hədəfin özünün təsviri:

cat installer.target
[Unit]
Description=My installer
Requires=multi-user.target 
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target 
AllowIsolate=yes
Wants=installer.service

Bu hədəf multi-user.target işə salındıqda və installer.service-ə zəng etdikdə başlayacaq. Bununla belə, bir neçə belə xidmət ola bilər.

cat installer.service
[Unit]
# описание
Description=installer interactive dialog

[Service]
# Запустить один раз, когда остальное будет запущенно
Type=idle
# Команда запуска - вызов скрипта
ExecStart=/usr/bin/installer.sh
# Интерактивное взаимодействие с пользователем через tty3
StandardInput=tty
TTYPath=/dev/tty3
TTYReset=yes
TTYVHangup=yes

[Install]
WantedBy=installer.target

Və nəhayət, icra olunan skript nümunəsi:

#!/bin/bash
# Переходим в tty3
chvt 3
echo "Install, y/n ?"
read user_answer

Əsas odur ki, final.target - sistemin başlanğıcda çatacağı hədəfi seçməkdir. Başlanğıc prosesində systemd asılılıqlardan keçəcək və lazım olan hər şeyi işə salacaq.
Final.target seçmək üçün müxtəlif yollar var, mən bunun üçün yükləyici seçimindən istifadə etdim.

Son buraxılış belə görünür:

  1. Yükləyici başlayır
  2. Yükləyici final.target parametrini keçərək mikroproqramı işə salmağa başlayır
  3. Systemd sistemi işə salmağa başlayır. Asılılıqları vasitəsilə (məsələn, multi-user.target) ardıcıl olaraq basic.target-dən installer.target və ya work.target-ə keçir. Sonuncu sistemi istədiyiniz rejimdə işləməyə gətirir

Mikroproqramın işə salınması üçün hazırlanması

Firmware yaratarkən, həmişə işə başlayanda sistemin vəziyyətini bərpa etmək və bağlandıqda onu saxlamaq vəzifəsi yaranır. Dövlət konfiqurasiya faylları, verilənlər bazası zibilləri, interfeys parametrləri və s.

Systemd eyni hədəfdəki prosesləri paralel olaraq icra edir. Skriptlərin başlanğıc ardıcıllığını təyin etməyə imkan verən asılılıqlar var.

Bu mənim layihəmdə necə işləyir ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. Sistem başlayır
  2. settings_restore.service xidməti işə salındı.O, data bölməsində settings.txt faylının olub-olmadığını yoxlayır. Əgər orada deyilsə, onun yerinə istinad faylı yerləşdirilir.Sonra sistem parametrləri bərpa olunur:
    • administrator parolu
    • host adı,
    • vaxt zonası
    • yerli
    • Bütün medianın istifadə edilib-edilmədiyini müəyyən edir. Varsayılan olaraq, şəkil ölçüsü kiçikdir - kopyalamaq və mediaya yazmaq asanlığı üçün. Başlanğıcda o, hələ də istifadə olunmamış yerin olub olmadığını yoxlayır. Əgər varsa, disk yenidən bölünür.
    • MAC ünvanından maşın identifikatoru yaradılır. Bu, eyni ünvanı DHCP vasitəsilə əldə etmək üçün vacibdir
    • Şəbəkə parametrləri
    • Günlüklərin ölçüsünü məhdudlaşdırır
    • Xarici sürücü işə hazırlanır (müvafiq seçim aktivdirsə və sürücü yenidirsə)
  3. Postgresq-a başlayın
  4. Bərpa xidməti başlayır. Zabbix-in özünü və onun verilənlər bazasını hazırlamaq lazımdır:
    • Zabbix verilənlər bazasının artıq olub olmadığını yoxlayır. Əgər deyilsə, o, başlanğıc zibillərindən yaradılır (zabbix ilə birlikdə)
    • saat qurşaqlarının siyahısı yaradılır (onları veb interfeysində göstərmək üçün lazımdır)
    • Cari IP tapıldı, məsələdə göstərilir (konsola daxil olmaq üçün dəvət)
  5. Dəvət dəyişir - İşləməyə hazır ifadəsi görünür
  6. Firmware istifadəyə hazırdır

Xidmət faylları vacibdir, onlar işə salınma ardıcıllığını təyin edənlərdir

[Unit]
Description=restore system settings
Before=network.service prepare.service postgresql.service systemd-networkd.service systemd-resolved.service

[Service]
Type=oneshot
ExecStart=/usr/bin/settings_restore.sh

[Install]
WantedBy=multi-user.target

Gördüyünüz kimi, mən asılılıqları quraşdırdım ki, skriptim əvvəlcə işləsin və yalnız bundan sonra şəbəkə yüksəlsin və DBMS işə düşsün.

Və ikinci xidmət (zabbix hazırlığı)

#!/bin/sh
[Unit]
Description=monitor prepare system
After=postgresql.service settings_restore.service
Before=zabbix-server.service zabbix-agent.service

[Service]
Type=oneshot
ExecStart=/usr/bin/prepare.sh

[Install]
WantedBy=multi-user.target

Burada bir az daha mürəkkəbdir.Başlatma həm də multi-user.target-dədir, lakin postgresql DBMS və mənim settings_restore-u işə saldıqdan SONRA. Lakin zabbix xidmətlərinə başlamazdan ƏVVƏL.

Logrotate üçün taymer xidməti

Systemd CRON-u əvəz edə bilər. Ciddi. Üstəlik, dəqiqlik dəqiqəyə qədər deyil, saniyəyə qədərdir (lazım olduqda nə etməli) Və ya bir hadisədən vaxt aşımı ilə çağırılan monoton taymer yarada bilərsiniz.
Mənim yaratdığım maşının başlanğıcından vaxtı hesablayan monoton taymer idi.
Bunun üçün 2 fayl tələb olunacaq
logrotateTimer.service - xidmətin faktiki təsviri:

[Unit]
Description=run logrotate

[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300

Bu sadədir - işə salma əmrinin təsviri.
İkinci fayl logrotateTimer.timer taymerlərin işlədiyi yerdir:

[Unit]
Description=Run logrotate

[Timer]
OnBootSec=15min
OnUnitActiveSec=15min

[Install]
WantedBy=timers.target

Burada nə var:

  • taymer təsviri
  • Sistemin açılışından başlayaraq ilk başlanğıc vaxtı
  • növbəti buraxılışlar dövrü
  • Taymer xidmətindən asılılıq.Əslində bu, taymeri yaradan sətirdir

Bağlanarkən interaktiv skript və bağlama hədəfiniz

Başqa bir inkişafda, bir çox hərəkətləri yerinə yetirmək üçün maşını söndürməyin daha mürəkkəb bir versiyasını - öz hədəfim vasitəsilə etməli oldum. Adətən RemainAfterExit seçimi ilə bir dəfə xidmət yaratmaq tövsiyə olunur, lakin bu, interaktiv skript yaratmağınıza mane olur.

Ancaq fakt budur ki, ExecOnStop seçimi ilə işə salınan əmrlər TTY-dən kənarda icra olunur! Bunu yoxlamaq asandır - tty əmrini yapışdırın və onun çıxışını yadda saxlayın.

Buna görə də hədəfim vasitəsilə bağlamanı həyata keçirdim. Mən 100% doğru olduğumu iddia etmirəm, amma işləyir!
Necə edildi (ümumi mənada):
Heç kimdən asılı olmayan my_shutdown.target hədəfi yaratdım:
my_shutdown.target

[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service 

Bu hədəfə gedərkən (systemctl isolate my_shutdwn.target vasitəsilə) o, my_shutdown.service xidmətini işə saldı, vəzifəsi sadədir - my_shutdown.sh skriptini yerinə yetirmək:

[Unit]
Description=MY shutdown

[Service]
Type=oneshot
ExecStart=/usr/bin/my_shutdown.sh
StandardInput=tty
TTYPath=/dev/tty3
TTYReset=yes
TTYVHangup=yes

WantedBy=my_shutdown.target

  • Bu skriptin içərisində mən lazımi hərəkətləri yerinə yetirirəm. Çeviklik və rahatlıq üçün hədəfə çoxlu skript əlavə edə bilərsiniz:

my_shutdown.sh

#!/bin/bash --login
if [ -f /tmp/reboot ];then
    command="systemctl reboot"
elif [ -f /tmp/shutdown ]; then
    command="systemctl poweroff"
fi
#Вот здесь нужные команды
#Например, cp /home/user/data.txt /storage/user/
    $command

Qeyd. /tmp/reboot və /tmp/sutdown fayllarından istifadə etməklə. Parametrlərlə hədəfə zəng edə bilməzsiniz. Yalnız servis mümkündür.

Amma işdə çeviklik və zəmanətli hərəkətlər sırasına sahib olmaq üçün hədəfdən istifadə edirəm.

Ancaq ən maraqlısı sonradan gəldi. Maşını söndürmək/yenidən işə salmaq lazımdır. Və 2 seçim var:

  • Yenidən yükləmə, söndürmə və digər əmrləri (onlar hələ də systemctl ilə simvolik əlaqədir) skriptinizlə əvəz edin.Skript daxilində my_shutdown.target ünvanına keçin. Və hədəf daxilindəki skriptlər daha sonra birbaşa systemctl-ə zəng edirlər, məsələn, systemctl reboot
  • Daha sadə seçimdir, amma xoşuma gəlmir. Bütün interfeyslərdə shutdown/reboot/digər zəng etməyin, birbaşa hədəf systemctl isolate my_shutdown.target-ə zəng edin.

Mən birinci variantı seçdim. Systemd-də reboot (qüvvəni söndürmə kimi) systemd ilə simvolik əlaqədir.

ls -l /sbin/poweroff 
lrwxrwxrwx 1 root root 14 сен 30 18:23 /sbin/poweroff -> /bin/systemctl

Buna görə də, onları öz skriptlərinizlə əvəz edə bilərsiniz:
reboot

#!/bin/sh
    touch /tmp/reboot
    sudo systemctl isolate my_shutdown.target
fi

Mənbə: www.habr.com

Добавить комментарий