Systemd, ఇంటరాక్టివ్ స్క్రిప్ట్‌లు మరియు టైమర్‌లు

Systemd, ఇంటరాక్టివ్ స్క్రిప్ట్‌లు మరియు టైమర్‌లు

పరిచయం

Linux కోసం అభివృద్ధి చేస్తున్నప్పుడు, సిస్టమ్ ఆన్ చేయబడినప్పుడు లేదా షట్ డౌన్ అయినప్పుడు అమలు చేయబడే ఇంటరాక్టివ్ స్క్రిప్ట్‌లను సృష్టించే పని తలెత్తుతుంది. సిస్టమ్ Vలో ఇది సులభం, కానీ systemdతో ఇది సర్దుబాట్లు చేస్తుంది. కానీ దాని స్వంత టైమర్లు ఉండవచ్చు.

మనకు లక్ష్యాలు ఎందుకు అవసరం?

సిస్టమ్ V -initలో టార్గెట్ రన్‌లెవల్ యొక్క అనలాగ్‌గా పనిచేస్తుందని తరచుగా వ్రాయబడుతుంది. నేను ప్రాథమికంగా ఏకీభవించను. వాటిలో మరిన్ని ఉన్నాయి మరియు మీరు ప్యాకేజీలను సమూహాలుగా విభజించవచ్చు మరియు ఉదాహరణకు, ఒక ఆదేశంతో సేవల సమూహాన్ని ప్రారంభించి అదనపు చర్యలను చేయవచ్చు. అంతేకాకుండా, వారికి సోపానక్రమం లేదు, డిపెండెన్సీలు మాత్రమే ఉంటాయి.

ఇంటరాక్టివ్ స్క్రిప్ట్‌ని అమలు చేయడంతో ప్రారంభించబడినప్పుడు లక్ష్యం యొక్క ఉదాహరణ (ఫీచర్ ఓవర్‌వ్యూ).

లక్ష్యం యొక్క వివరణ:

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

అతి ముఖ్యమైన విషయం ఫైనల్.టార్గెట్‌ని ఎంచుకోవడం - సిస్టమ్ స్టార్టప్‌లో చేరుకోవాల్సిన లక్ష్యం. ప్రారంభ ప్రక్రియ సమయంలో, systemd డిపెండెన్సీల ద్వారా వెళ్లి దానికి అవసరమైన ప్రతిదాన్ని లాంచ్ చేస్తుంది.
final.target ఎంచుకోవడానికి వివిధ మార్గాలు ఉన్నాయి, నేను దీని కోసం లోడర్ ఎంపికను ఉపయోగించాను.

చివరి ప్రయోగం ఇలా కనిపిస్తుంది:

  1. బూట్‌లోడర్ ప్రారంభమవుతుంది
  2. బూట్‌లోడర్ final.target పరామితిని పాస్ చేయడం ద్వారా ఫర్మ్‌వేర్‌ను ప్రారంభించడం ప్రారంభిస్తుంది
  3. Systemd సిస్టమ్‌ను ప్రారంభించడం ప్రారంభిస్తుంది. వాటి డిపెండెన్సీల ద్వారా (ఉదాహరణకు, multi-user.target) basic.target నుండి ఇన్‌స్టాలర్.టార్గెట్ లేదా work.targetకి వరుసగా వెళుతుంది. తరువాతి సిస్టమ్‌ను కావలసిన రీతిలో పని చేయడానికి తీసుకువస్తుంది

లాంచ్ కోసం ఫర్మ్‌వేర్‌ను సిద్ధం చేస్తోంది

ఫర్మ్‌వేర్‌ను సృష్టించేటప్పుడు, స్టార్టప్‌లో సిస్టమ్ స్థితిని పునరుద్ధరించడం మరియు మూసివేసేటప్పుడు దాన్ని సేవ్ చేయడం ఎల్లప్పుడూ పని చేస్తుంది. రాష్ట్రం అంటే కాన్ఫిగరేషన్ ఫైల్‌లు, డేటాబేస్ డంప్‌లు, ఇంటర్‌ఫేస్ సెట్టింగ్‌లు మొదలైనవి.

Systemd ఒకే లక్ష్యంలో ప్రక్రియలను సమాంతరంగా నడుపుతుంది. స్క్రిప్ట్‌ల ప్రారంభ క్రమాన్ని నిర్ణయించడానికి మిమ్మల్ని అనుమతించే డిపెండెన్సీలు ఉన్నాయి.

ఇది నా ప్రాజెక్ట్‌లో ఎలా పని చేస్తుంది ( https://habr.com/ru/post/477008/ https://github.com/skif-web/monitor)

  1. సిస్టమ్ ప్రారంభమవుతుంది
  2. settings_restore.service సర్వీస్ ప్రారంభించబడింది. ఇది డేటా విభాగంలో settings.txt ఫైల్ ఉనికిని తనిఖీ చేస్తుంది. అది లేనట్లయితే, దాని స్థానంలో రిఫరెన్స్ ఫైల్ ఉంచబడుతుంది. తర్వాత, సిస్టమ్ సెట్టింగ్‌లు పునరుద్ధరించబడతాయి:
    • నిర్వాహకుని పాస్వర్డ్
    • హోస్ట్ పేరు,
    • సమయమండలం
    • లొకేల్
    • అన్ని మీడియా ఉపయోగించబడుతుందో లేదో నిర్ణయిస్తుంది. డిఫాల్ట్‌గా, చిత్ర పరిమాణం చిన్నది - మీడియాకు కాపీ చేయడం మరియు రికార్డింగ్ చేయడం సౌలభ్యం కోసం. ప్రారంభంలో, ఇది ఇప్పటికీ ఉపయోగించని స్థలం ఉందో లేదో తనిఖీ చేస్తుంది. ఉన్నట్లయితే, డిస్క్ పునఃవిభజన చేయబడుతుంది.
    • MAC చిరునామా నుండి మెషిన్-ఐడిని రూపొందిస్తోంది. DHCP ద్వారా అదే చిరునామాను పొందడం కోసం ఇది ముఖ్యమైనది
    • నెట్వర్క్ అమరికలు
    • లాగ్‌ల పరిమాణాన్ని పరిమితం చేస్తుంది
    • బాహ్య డ్రైవ్ పని కోసం సిద్ధం చేయబడుతోంది (సంబంధిత ఎంపిక ప్రారంభించబడి ఉంటే మరియు డ్రైవ్ కొత్తది అయితే)
  3. postgresq ప్రారంభించండి
  4. పునరుద్ధరణ సేవ ప్రారంభమవుతుంది. Zabbix మరియు దాని డేటాబేస్‌ను సిద్ధం చేయడానికి ఇది అవసరం:
    • ఇప్పటికే zabbix డేటాబేస్ ఉందో లేదో తనిఖీ చేస్తుంది. కాకపోతే, ఇది ఇనిషియలైజేషన్ డంప్‌ల నుండి సృష్టించబడుతుంది (జాబిక్స్‌తో సహా)
    • సమయ మండలాల జాబితా సృష్టించబడింది (వాటిని వెబ్ ఇంటర్‌ఫేస్‌లో ప్రదర్శించడానికి అవసరం)
    • ప్రస్తుత IP కనుగొనబడింది, ఇది సమస్యలో ప్రదర్శించబడుతుంది (కన్సోల్‌కు లాగిన్ చేయడానికి ఆహ్వానం)
  5. ఆహ్వానం మారుతుంది - పని చేయడానికి సిద్ధంగా ఉంది అనే పదబంధం కనిపిస్తుంది
  6. ఫర్మ్‌వేర్ ఉపయోగం కోసం సిద్ధంగా ఉంది

సేవా ఫైల్‌లు ముఖ్యమైనవి, అవి వాటి ప్రారంభ క్రమాన్ని సెట్ చేస్తాయి

[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 మరియు నా సెట్టింగ్_రిస్టోర్‌ను ప్రారంభించిన తర్వాత. కానీ zabbix సేవలను ప్రారంభించడానికి ముందు.

లోగ్రోటేట్ కోసం టైమర్ సేవ

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

ఇక్కడ ఏమి ఉంది:

  • టైమర్ వివరణ
  • మొదటి ప్రారంభ సమయం, సిస్టమ్ బూట్ నుండి ప్రారంభమవుతుంది
  • తదుపరి ప్రయోగాల కాలం
  • టైమర్ సేవపై ఆధారపడటం. నిజానికి, ఇది టైమర్‌ను తయారు చేసే స్ట్రింగ్

షట్ డౌన్ చేస్తున్నప్పుడు ఇంటరాక్టివ్ స్క్రిప్ట్ మరియు మీ షట్‌డౌన్ లక్ష్యం

మరొక డెవలప్‌మెంట్‌లో, నేను మెషీన్‌ను ఆఫ్ చేయడంలో మరింత సంక్లిష్టమైన సంస్కరణను చేయాల్సి వచ్చింది - నా స్వంత లక్ష్యం ద్వారా, అనేక చర్యలను చేయడానికి. 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 ఎంపికలు ఉన్నాయి:

  • మీ స్క్రిప్ట్‌తో రీబూట్, షట్‌డౌన్ మరియు ఇతర ఆదేశాలను (అవి ఇప్పటికీ systemctlకు సిమ్‌లింక్‌లు) భర్తీ చేయండి. స్క్రిప్ట్ లోపల, my_shutdown.targetకి వెళ్లండి. మరియు లక్ష్యం లోపల ఉన్న స్క్రిప్ట్‌లు నేరుగా systemctlని కాల్ చేస్తాయి, ఉదాహరణకు, systemctl రీబూట్
  • సరళమైన ఎంపిక, కానీ నాకు ఇది ఇష్టం లేదు. అన్ని ఇంటర్‌ఫేస్‌లలో, షట్‌డౌన్/రీబూట్/ఇతర అని కాల్ చేయవద్దు, కానీ నేరుగా టార్గెట్ systemctl ఐసోలేట్ my_shutdown.targetకి కాల్ చేయండి

నేను మొదటి ఎంపికను ఎంచుకున్నాను. systemdలో, రీబూట్ (పవర్‌ఆఫ్ వంటివి) systemdకి సిమ్‌లింక్‌లు.

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

కాబట్టి, మీరు వాటిని మీ స్వంత స్క్రిప్ట్‌లతో భర్తీ చేయవచ్చు:
రీబూట్

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

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి