Introduzione
Quandu u sviluppu per Linux, u compitu di creà scripts interattivi chì sò eseguiti quandu u sistema hè attivatu o chjusu sorge. In u sistema V questu era faciule, ma cù systemd faci aghjustamenti. Ma pò avè u so propiu timer.
Perchè avemu bisognu di mira ?
Hè spessu scrittu chì u target serve cum'è un analogu di runlevel in u sistema V -init. Fundamentalmente ùn sò d'accordu. Ci sò più di elli è pudete dividisce i pacchetti in gruppi è, per esempiu, lanciate un gruppu di servizii cù un cumandamentu è eseguite azzioni supplementari. Inoltre, ùn anu micca gerarchia, solu dipendenze.
Esempiu di destinazione quandu attivatu (panoramica di e funzioni) cù script interattivu in esecuzione
Descrizzione di u scopu stessu:
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
Stu scopu principia quandu multi-user.target hè lanciatu è chjama installer.service. Tuttavia, ci ponu esse parechji tali servizii.
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
È infine, un esempiu di u script chì hè eseguitu:
#!/bin/bash
# Переходим в tty3
chvt 3
echo "Install, y/n ?"
read user_answer
A più impurtante hè di selezziunà final.target - u scopu à quale u sistema deve ghjunghje à l'iniziu. Durante u prucessu di startup, systemd passerà per e dipendenze è lanciarà tuttu ciò chì hà bisognu.
Ci hè parechje manere di selezziunà final.target, aghju utilizatu l'opzione di caricatore per questu.
U lanciu finale hè cusì:
- U bootloader principia
- U bootloader accumincia a lanciari u firmware passendu u paràmetru final.target
- Systemd principia à inizià u sistema. Sequentially va à installer.target o work.target da basic.target attraversu e so dependenze (per esempiu, multi-user.target). L'ultimi portanu u sistema à travaglià in u modu desideratu
Preparazione di u firmware per u lanciu
Quandu crea u firmware, u compitu sempre nasce di restaurà u statu di u sistema à l'iniziu è di salvà quandu si chjude. Statu significa schedarii di cunfigurazione, dumps di basa di dati, paràmetri di l'interfaccia, etc.
Systemd esegue i prucessi in u stessu scopu in parallelu. Ci sò dipendenze chì permettenu di determinà a sequenza di startup di scripts.
Cumu funziona in u mo prughjettu (
- U sistema principia
- Hè lanciatu u serviziu settings_restore.service, verifica a presenza di u schedariu settings.txt in a sezione di dati. Se ùn hè micca quì, allora un schedariu di riferimentu hè piazzatu in u so locu, dopu, i paràmetri di u sistema sò restaurati:
- password amministratore
- hostname,
- fusu orariu
- locale
- Determina se tutti i media sò usati. Per automaticamente, a dimensione di l'imaghjini hè chjuca - per facilità di copia è arregistramentu à i media. À l'iniziu, verifica per vede s'ellu ci hè ancu spaziu inutilizatu. Se ci hè, u discu hè ripartizione.
- Generating machine-id da l'indirizzu MAC. Questu hè impurtante per ottene u stessu indirizzu via DHCP
- Paràmetri di a rete
- Limita a dimensione di logs
- L'unità esterna hè stata preparata per u travagliu (se l'opzione currispondente hè attivata è l'unità hè nova)
- Cumincià postgresq
- U serviziu di restaurazione principia. Hè necessariu di preparà zabbix stessu è a so basa di dati:
- Verifica s'ellu ci hè digià una basa di dati zabbix. Se no, hè creatu da dumps d'inizializazione (inclusi cù zabbix)
- una lista di fusi orari hè creatu (necessariu per vede in l'interfaccia web)
- L'IP attuale hè trovata, hè visualizata in u prublema (invitu à accede à a cunsola)
- L'invitu cambia - a frasa Ready to work appare
- U firmware hè prontu per l'usu
I schedarii di serviziu sò impurtanti, sò quelli chì stabiliscenu a sequenza di u so lanciamentu
[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
Comu pudete vede, aghju installatu dependenzii in modu chì u mo script hà da travaglià prima, è solu allora a reta cullà è u DBMS principia.
È u sicondu serviziu (preparazione 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
Hè un pocu più cumplicatu quì.U lanciamentu hè ancu in multi-user.target, ma DOPO avè principiatu u DBMS postgresql è u mo setting_restore. Ma prima di inizià i servizii di zabbix.
Serviziu di timer per logrotate
Systemd pò rimpiazzà CRON. Seriu. Inoltre, a precisione ùn hè micca finu à u minutu, ma finu à u sicondu (chì s'ellu hè necessariu) O pudete creà un timer monotonu, chjamatu da un timeout da un avvenimentu.
Era u timer monotonu chì conta u tempu da u principiu di a macchina chì aghju creatu.
Questu averebbe bisognu di 2 schedari
logrotateTimer.service - a descrizzione attuale di u serviziu:
[Unit]
Description=run logrotate
[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300
Hè simplice - descrizzione di u cumandamentu di lanciamentu.
U sicondu schedariu logrotateTimer.timer hè induve i timers travaglianu:
[Unit]
Description=Run logrotate
[Timer]
OnBootSec=15min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.target
Chì ci hè quì:
- descrizzione di u timer
- Prima ora di partenza, partendu da u boot di u sistema
- periodo di ulteriori lanci
- Dipendenza di u serviziu di timer.In fattu, questu hè a stringa chì face u timer
Scrittura interattiva quandu si chjude è u vostru scopu di chjusu
In un altru sviluppu, aghju avutu à fà una versione più cumplessa di disattivà a macchina - attraversu u mo propiu scopu, per fà parechje azzioni. Di solitu hè cunsigliatu per creà un serviziu oneshot cù l'opzione RemainAfterExit, ma questu impedisce di creà un script interattivu.
Ma u fattu hè chì i cumandamenti lanciati da l'opzione ExecOnStop sò eseguiti fora di u TTY! Hè faciule di verificà - incollà u cumandamentu tty è salvà a so output.
Dunque, aghju implementatu l'arrestu attraversu u mo mira. Ùn dicenu micca esse 100% currettu, ma funziona!
Cumu hè statu fattu (in termini generale):
Aghju creatu un target my_shutdown.target, chì ùn dipende micca di nimu:
my_shutdown.target
[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service
Quandu andava à questu scopu (via systemctl isolate my_shutdwn.target), hà lanciatu u serviziu my_shutdown.service, u so compitu hè simplice - per eseguisce u script 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
- Dentru stu script aghju realizatu l'azzioni necessarii. Pudete aghjunghje parechji script à u target per flessibilità è comodità:
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
Nota. Utilizendu i schedarii /tmp/reboot è /tmp/shutdown. Ùn pudete micca chjamà target cù parametri. Solu u serviziu hè pussibule.
Ma aghju utilizatu u mira per avè flessibilità in u travagliu è un ordine garantitu di l'azzioni.
Tuttavia, u più interessante hè vinutu dopu. A macchina deve esse disattivata / riavviata. È ci sò 2 opzioni:
- Sustituisci u reboot, shutdown è altri cumandamenti (sò sempre ligami simbolichi à systemctl) cù u vostru script.Intra u script, andate à my_shutdown.target. È i scripts in u target poi chjamanu systemctl direttamente, per esempiu, systemctl reboot
- Una opzione più simplice, ma ùn mi piace micca. In tutte l'interfaccia, ùn chjamate micca shutdown / reboot / other, ma chjamate direttamente u sistema di destinazione isolate my_shutdown.target
Aghju sceltu a prima opzione. In systemd, reboot (cum'è poweroff) sò ligami simbolichi à systemd.
ls -l /sbin/poweroff
lrwxrwxrwx 1 root root 14 сен 30 18:23 /sbin/poweroff -> /bin/systemctl
Dunque, pudete rimpiazzà cù i vostri scripts:
reboot
#!/bin/sh
touch /tmp/reboot
sudo systemctl isolate my_shutdown.target
fi
Source: www.habr.com