Ներածություն
Linux-ի համար մշակելիս խնդիր է առաջանում ստեղծել ինտերակտիվ սկրիպտներ, որոնք գործարկվում են, երբ համակարգը միացված է կամ անջատվում է: V համակարգում դա հեշտ էր, բայց systemd-ով այն ճշգրտումներ է անում: Բայց այն կարող է ունենալ իր ժամանակաչափերը:
Ինչու՞ են մեզ անհրաժեշտ թիրախները:
Հաճախ գրվում է, որ թիրախը V -init համակարգում ծառայում է որպես runlevel-ի անալոգ: Ես սկզբունքորեն համաձայն չեմ. Դրանք ավելի շատ են, և դուք կարող եք փաթեթները բաժանել խմբերի և, օրինակ, մեկ հրամանով գործարկել ծառայությունների խումբ և կատարել լրացուցիչ գործողություններ: Ավելին, նրանք չունեն հիերարխիա, միայն կախվածություն:
Թիրախի օրինակ, երբ միացված է (հատկանիշի ակնարկ) գործարկվող ինտերակտիվ սցենարով
Ինքն թիրախի նկարագրությունը.
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
Այս թիրախը կսկսվի, երբ multi-user.target-ը գործարկվի և զանգի installer.service: Այնուամենայնիվ, կարող են լինել մի քանի նման ծառայություններ:
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
Եվ վերջապես, կատարվող սցենարի օրինակ.
#!/bin/bash
# Переходим в tty3
chvt 3
echo "Install, y/n ?"
read user_answer
Ամենակարևորը final.target-ի ընտրությունն է՝ այն թիրախը, որին համակարգը պետք է հասնի գործարկման ժամանակ: Գործարկման գործընթացում systemd-ը կանցնի կախվածությունների միջով և կգործարկի այն ամենը, ինչ անհրաժեշտ է:
Կան final.target ընտրելու տարբեր եղանակներ, ես դրա համար օգտագործել եմ loader տարբերակը։
Վերջնական մեկնարկն այսպիսի տեսք ունի.
- Բեռնախցիկը սկսվում է
- Bootloader-ը սկսում է գործարկել որոնվածը` անցնելով final.target պարամետրը
- Systemd-ը սկսում է գործարկել համակարգը: Հերթականորեն գնում է installer.target կամ work.target հիմնական.target-ից իրենց կախվածությունների միջոցով (օրինակ՝ multi-user.target): Վերջիններս համակարգը աշխատանքի են բերում ցանկալի ռեժիմով
Ծրագրաշարի պատրաստում գործարկման համար
Որոնվածը ստեղծելիս միշտ խնդիր է առաջանում վերականգնել համակարգի վիճակը գործարկման ժամանակ և պահպանել այն անջատելիս: Պետությունը նշանակում է կազմաձևման ֆայլեր, տվյալների բազայի աղբանոցներ, ինտերֆեյսի կարգավորումներ և այլն:
Systemd-ը զուգահեռաբար կատարում է գործընթացները նույն թիրախում: Կան կախվածություններ, որոնք թույլ են տալիս որոշել սկրիպտների գործարկման հաջորդականությունը:
Ինչպես է այն աշխատում իմ նախագծում (
- Համակարգը սկսվում է
- Գործարկվում է settings_restore.service ծառայությունը, որը ստուգում է տվյալների բաժնում settings.txt ֆայլի առկայությունը: Եթե այն չկա, ապա դրա տեղում տեղադրվում է տեղեկատու ֆայլ: Հաջորդը, համակարգի կարգավորումները վերականգնվում են.
- ադմինիստրատորի գաղտնաբառը
- հյուրընկալողի անունը,
- Ժամային գոտի
- տեղայնությունը
- Որոշում է, թե արդյոք օգտագործվում են բոլոր լրատվամիջոցները: Լռելյայնորեն, պատկերի չափը փոքր է. պատճենելու և մեդիա ձայնագրման հեշտության համար: Գործարկման ժամանակ այն ստուգում է՝ արդյոք դեռ չօգտագործված տարածք կա: Եթե կա, ապա սկավառակը վերաբաշխվում է:
- Մեքենայի ID-ի ստեղծում MAC հասցեից: Սա կարևոր է DHCP-ի միջոցով նույն հասցեն ստանալու համար
- Ցանցի կարգավորումներ
- Սահմանափակում է գերանների չափերը
- Արտաքին սկավառակը պատրաստվում է աշխատանքի (եթե համապատասխան տարբերակը միացված է և սկավառակը նոր է)
- Սկսեք postgresq
- Վերականգնման ծառայությունը սկսվում է: Այն անհրաժեշտ է ինքնին zabbix-ը և դրա տվյալների բազան պատրաստելու համար.
- Ստուգում է՝ արդյոք արդեն կա zabbix տվյալների բազա: Եթե ոչ, այն ստեղծվում է սկզբնավորման աղբանոցներից (ներառյալ zabbix-ը)
- ստեղծվում է ժամային գոտիների ցանկ (անհրաժեշտ է դրանք վեբ ինտերֆեյսում ցուցադրելու համար)
- Ընթացիկ IP-ն գտնվել է, այն ցուցադրվում է հարցում (վահանակ մուտք գործելու հրավեր)
- Հրավերը փոխվում է՝ հայտնվում է Ready to work արտահայտությունը
- Որոնվածը պատրաստ է օգտագործման
Ծառայության ֆայլերը կարևոր են, դրանք են, որոնք սահմանում են դրանց գործարկման հաջորդականությունը
[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
Ինչպես տեսնում եք, ես տեղադրեցի կախվածություններ, որպեսզի իմ սցենարը սկզբում աշխատի, և միայն դրանից հետո ցանցը բարձրանա և սկսվի DBMS-ը։
Եվ երկրորդ ծառայությունը (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
Այստեղ մի փոքր ավելի բարդ է: Գործարկումը նույնպես multi-user.target-ում է, բայց postgresql DBMS-ն ու իմ setting_restore-ը սկսելուց ՀԵՏՈ: Բայց մինչ zabbix ծառայությունները սկսելը:
Ժամաչափի ծառայություն logrotate-ի համար
Systemd-ը կարող է փոխարինել CRON-ին: Լուրջ. Ընդ որում, ճշգրտությունը մինչև րոպեն չէ, այլ մինչև վայրկյանը (բա եթե դրա կարիքը լինի) Կամ կարող եք ստեղծել միապաղաղ ժմչփ, որը կոչվում է իրադարձության ժամանակացույցով:
Դա միապաղաղ ժմչփն էր, որը հաշվում է ժամանակը իմ ստեղծած մեքենայի մեկնարկից:
Սա կպահանջի 2 ֆայլ
logrotateTimer.service - ծառայության իրական նկարագրությունը.
[Unit]
Description=run logrotate
[Service]
ExecStart=logrotate /etc/logrotate.conf
TimeoutSec=300
Դա պարզ է՝ գործարկման հրամանի նկարագրությունը:
Երկրորդ ֆայլը logrotateTimer.timer այն վայրն է, որտեղ աշխատում են ժամանակաչափերը.
[Unit]
Description=Run logrotate
[Timer]
OnBootSec=15min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.target
Ինչ կա այստեղ.
- ժմչփի նկարագրություն
- Առաջին մեկնարկի ժամանակը, սկսած համակարգի բեռնումից
- հետագա գործարկումների ժամանակահատվածը
- Կախվածություն ժմչփի ծառայությունից: Փաստորեն, սա այն տողն է, որը ստեղծում է ժամանակաչափը
Ինտերակտիվ սցենար անջատման ժամանակ և ձեր անջատման թիրախը
Մեկ այլ մշակման ժամանակ ես պետք է անեի մեքենան անջատելու ավելի բարդ տարբերակ՝ իմ սեփական թիրախի միջոցով, որպեսզի կատարեի բազմաթիվ գործողություններ: Սովորաբար խորհուրդ է տրվում ստեղծել oneshot ծառայություն RemainAfterExit տարբերակով, սակայն դա ձեզ խանգարում է ստեղծել ինտերակտիվ սցենար:
Բայց փաստն այն է, որ ExecOnStop տարբերակով գործարկված հրամանները կատարվում են TTY-ից դուրս: Հեշտ է ստուգել՝ տեղադրեք tty հրամանը և պահպանեք դրա արդյունքը:
Հետևաբար, ես իրականացրեցի անջատումը իմ թիրախի միջոցով: Ես չեմ պնդում, որ 100% ճիշտ եմ, բայց դա աշխատում է:
Ինչպես դա արվեց (ընդհանուր ձևով).
Ես ստեղծեցի թիրախ my_shutdown.target, որը կախված չէր որևէ մեկից.
my_shutdown.target
[Unit]
Description=my shutdown
AllowIsolate=yes
Wants=my_shutdown.service
Այս թիրախին անցնելիս (systemctl isolate my_shutdwn.target-ի միջոցով), այն գործարկեց my_shutdown.service ծառայությունը, որի խնդիրը պարզ է՝ գործարկել 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
- Այս սցենարի ներսում ես կատարում եմ անհրաժեշտ գործողությունները: Ճկունության և հարմարության համար կարող եք թիրախին ավելացնել բազմաթիվ սցենարներ.
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
Նշում. Օգտագործելով /tmp/reboot և /tmp/shutdown ֆայլերը: Դուք չեք կարող զանգահարել թիրախը պարամետրերով: Հնարավոր է միայն սպասարկում։
Բայց ես օգտագործում եմ թիրախը աշխատանքի մեջ ճկունություն և գործողությունների երաշխավորված կարգ ունենալու համար։
Այնուամենայնիվ, ամենահետաքրքիրը եկավ ավելի ուշ. Մեքենան պետք է անջատվի/վերագործարկվի: Եվ կա 2 տարբերակ.
- Փոխարինեք reboot, shutdown և այլ հրամանները (դրանք դեռևս systemctl-ի սիմվոլիկներ են) ձեր սկրիպտով: Սկրիպտի ներսում գնացեք my_shutdown.target: Իսկ թիրախի ներսում գտնվող սկրիպտները անմիջապես կանչում են systemctl, օրինակ՝ systemctl reboot
- Ավելի պարզ տարբերակ, բայց ինձ դուր չի գալիս: Բոլոր ինտերֆեյսներում մի զանգահարեք shutdown/reboot/other, այլ ուղղակիորեն զանգահարեք թիրախային համակարգըctl isolate my_shutdown.target:
Ես ընտրեցի առաջին տարբերակը. Systemd-ում reboot-ը (ինչպես poweroff-ը) սիմվոլիկ է systemd-ին:
ls -l /sbin/poweroff
lrwxrwxrwx 1 root root 14 сен 30 18:23 /sbin/poweroff -> /bin/systemctl
Հետևաբար, դուք կարող եք դրանք փոխարինել ձեր սեփական սցենարներով.
reboot
#!/bin/sh
touch /tmp/reboot
sudo systemctl isolate my_shutdown.target
fi
Source: www.habr.com