Paraqitje
Kur zhvillohet për Linux, lind detyra e krijimit të skripteve interaktive që ekzekutohen kur sistemi ndizet ose mbyllet. Në sistemin V kjo ishte e lehtë, por me systemd bën rregullime. Por mund të ketë kohëmatësit e vet.
Pse na duhen objektivat?
Shpesh shkruhet se objektivi shërben si një analog i nivelit të ekzekutimit në sistemin V-init. Në thelb nuk jam dakord. Ka më shumë prej tyre dhe ju mund të ndani paketat në grupe dhe, për shembull, të nisni një grup shërbimesh me një komandë dhe të kryeni veprime shtesë. Për më tepër, ata nuk kanë hierarki, por vetëm varësi.
Shembull i objektivit kur aktivizohet (përmbledhje e veçorive) me ekzekutimin e skriptit interaktiv
Përshkrimi i vetë objektivit:
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
Ky objektiv do të fillojë kur të hapet multi-user.target dhe të telefonojë installer.service. Sidoqoftë, mund të ketë disa shërbime të tilla.
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
Dhe së fundi, një shembull i skenarit që po ekzekutohet:
#!/bin/bash
# Переходим в tty3
chvt 3
echo "Install, y/n ?"
read user_answer
Gjëja më e rëndësishme është të zgjidhni final.target - objektivin në të cilin sistemi duhet të arrijë në fillimin. Gjatë procesit të fillimit, systemd do të kalojë varësitë dhe do të nisë gjithçka që i nevojitet.
Ka mënyra të ndryshme për të zgjedhur final.target, unë përdora opsionin loader për këtë.
Nisja përfundimtare duket kështu:
- Nis ngarkuesi
- Bootloader fillon lëshimin e firmuerit duke kaluar parametrin final.target
- Systemd fillon të nisë sistemin. Në mënyrë sekuenciale shkon te installer.target ose work.target nga basic.target përmes varësive të tyre (për shembull, multi-user.target). Këto të fundit e sjellin sistemin të funksionojë në modalitetin e dëshiruar
Përgatitja e firmuerit për nisje
Kur krijoni firmware, gjithmonë lind detyra për të rivendosur gjendjen e sistemit në fillim dhe për ta ruajtur atë kur mbyllet. Gjendja nënkupton skedarët e konfigurimit, depozitat e bazës së të dhënave, cilësimet e ndërfaqes, etj.
Systemd drejton proceset në të njëjtin objektiv paralelisht. Ka varësi që ju lejojnë të përcaktoni sekuencën e fillimit të skripteve.
Si funksionon në projektin tim (
- Sistemi fillon
- Nis shërbimi settings_restore.service, i cili kontrollon praninë e skedarit settings.txt në seksionin e të dhënave. Nëse nuk është aty, atëherë në vend të tij vendoset një skedar referimi. Më pas, rikthehen cilësimet e sistemit:
- fjalëkalimi i administratorit
- emri i hostit,
- zonë kohore
- vendor
- Përcakton nëse të gjitha mediat janë duke u përdorur. Si parazgjedhje, madhësia e imazhit është e vogël - për lehtësinë e kopjimit dhe regjistrimit në media. Në fillim, kontrollon nëse ka ende hapësirë të papërdorur. Nëse ka, disku ndahet sërish.
- Gjenerimi i identifikimit të makinës nga adresa MAC. Kjo është e rëndësishme për marrjen e të njëjtës adresë përmes DHCP
- Cilësimet e rrjetit
- Kufizon madhësinë e shkrimeve
- Disku i jashtëm po përgatitet për punë (nëse opsioni përkatës është i aktivizuar dhe disku është i ri)
- Filloni postgresq
- Fillon shërbimi i rivendosjes. Është e nevojshme për të përgatitur vetë zabbix dhe bazën e të dhënave të tij:
- Kontrollon nëse ekziston tashmë një bazë të dhënash zabbix. Nëse jo, ai krijohet nga deponitë e inicializimit (përfshirë me zabbix)
- krijohet një listë e zonave kohore (të nevojshme për t'i shfaqur ato në ndërfaqen e internetit)
- IP-ja aktuale është gjetur, shfaqet në problem (ftesë për t'u identifikuar në tastierë)
- Ftesa ndryshon - shfaqet fraza Gati për të punuar
- Firmware është gati për përdorim
Skedarët e shërbimit janë të rëndësishëm, janë ata që vendosin sekuencën e nisjes së tyre
[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
Siç mund ta shihni, unë instalova varësi në mënyrë që skripti im të funksiononte fillimisht, dhe vetëm atëherë rrjeti do të ngrihej dhe do të fillonte DBMS.
Dhe shërbimi i dytë (përgatitja e zabbix)
#!/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
Është pak më e komplikuar këtu. Nisja është gjithashtu në multi-user.target, por PAS nisjes së postgresql DBMS dhe setting_restore tim. Por PARA fillimit të shërbimeve zabbix.
Shërbimi i kohëmatësit për logrotate
Systemd mund të zëvendësojë CRON. Seriozisht. Për më tepër, saktësia nuk është deri në minutë, por deri në sekondë (po nëse është e nevojshme).Ose mund të krijoni një kohëmatës monoton, të thirrur nga një kohëzgjatje nga një ngjarje.
Ishte kohëmatësi monoton që numëron kohën nga fillimi i makinës që krijova.
Kjo do të kërkojë 2 skedarë
logrotateTimer.service - përshkrimi aktual i shërbimit:
[Unit]
Description=run logrotate
[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300
Është e thjeshtë - përshkrimi i komandës së nisjes.
Skedari i dytë logrotateTimer.timer është vendi ku funksionojnë kohëmatësit:
[Unit]
Description=Run logrotate
[Timer]
OnBootSec=15min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.target
Çfarë ka këtu:
- përshkrimi i kohëmatësit
- Koha e parë e fillimit, duke filluar nga nisja e sistemit
- periudha e nisjeve të mëtejshme
- Varësia nga shërbimi i kohëmatësit.Në fakt, ky është vargu që bën kohëmatësin
Skript interaktiv kur mbyllet dhe objektivi juaj i mbylljes
Në një zhvillim tjetër, më duhej të bëja një version më kompleks të fikjes së makinës - përmes objektivit tim, në mënyrë që të kryeja shumë veprime. Zakonisht rekomandohet të krijoni një shërbim oneshot me opsionin RemainAfterExit, por kjo ju pengon të krijoni një skript interaktiv.
Por fakti është se komandat e lëshuara nga opsioni ExecOnStop ekzekutohen jashtë TTY! Është e lehtë për t'u kontrolluar - ngjitni komandën tty dhe ruani daljen e saj.
Prandaj, unë zbatova mbylljen përmes objektivit tim. Unë nuk pretendoj se jam 100% i saktë, por funksionon!
Si u bë (në terma të përgjithshëm):
Kam krijuar një objektiv my_shutdown.target, i cili nuk varej nga askush:
my_shutdown.objektiv
[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service
Kur shkon te ky objektiv (nëpërmjet systemctl izoluar my_shutdwn.target), ai nisi shërbimin my_shutdown.service, detyra e të cilit është e thjeshtë - të ekzekutojë skriptin my_shutdown.sh:
[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
- Brenda këtij skenari kryej veprimet e nevojshme. Ju mund të shtoni shumë skripta në objektiv për fleksibilitet dhe komoditet:
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
Shënim. Duke përdorur skedarët /tmp/reboot dhe /tmp/shutdown. Nuk mund të telefononi objektivin me parametra. Vetëm shërbimi është i mundur.
Por unë përdor objektivin për të pasur fleksibilitet në punë dhe një renditje të garantuar veprimesh.
Megjithatë, gjëja më interesante erdhi më vonë. Makina duhet të fiket/rifillohet. Dhe ka 2 opsione:
- Zëvendësoni reboot, shutdown dhe komanda të tjera (ato janë ende simlink për systemctl) me skriptin tuaj. Brenda skriptit, shkoni te my_shutdown.target. Dhe skriptet brenda objektivit më pas thërrasin systemctl direkt, për shembull, systemctl reboot
- Një opsion më i thjeshtë, por nuk më pëlqen. Në të gjitha ndërfaqet, mos telefononi shutdown/reboot/other, por thirrni drejtpërdrejt sistemin e synuarctl izoluar my_shutdown.target
Zgjodha opsionin e parë. Në systemd, reboot (si poweroff) janë lidhje simbolike me systemd.
ls -l /sbin/poweroff
lrwxrwxrwx 1 root root 14 сен 30 18:23 /sbin/poweroff -> /bin/systemctl
Prandaj, ju mund t'i zëvendësoni ato me skriptet tuaja:
reboot
#!/bin/sh
touch /tmp/reboot
sudo systemctl isolate my_shutdown.target
fi
Burimi: www.habr.com