A cím kicsit pongyola. De szeretném, hogy amikor ráklikkelnek a Leállításra, akkor még mielőtt az egész procedúra elkezdődik, lefutna egy program. Ezért azt a szkriptet melynek le kéne futnia, beletettem az /usr/lib/systemd/system-shutdown mappába shutdown kiterjesztéssel.. Viszont nem történt semmi.
Készítettem egy teszt fájlt, mely csak annyit tesz hogy 3 percig várakoztatja a gépet a kikapcsolás előtt. Ugyanide tettem, és az meg működik. Arra jutottam, hogy a szkript lefut ugyan, de a /dev/null-ban. Fogjuk rá hogy jó helyen van, de a legutolsó a sorban, holott a legelsőnek kellene lennie. Magyarul az ide berakott szkriptek melyeknek talán még fájlműveleteket is kellene folytatniuk, nem fognak működni, mert eddigre (addigra?) már lecsatolódott a fájlrendszer, kiléptek a felhasználók, és ennyi.
Jó, akkor jöjjön a service. Készítettem egyet, mely meghívta a szkriptemet, de ugyanez lett a jelenség. Nem történt semmi. Nos. Most ott tartok, hogy meg kell határoznom, melyik service után fusson le.
Jól gondolom-e hogy ez talán disztrófüggő? Ha pl. megadom hogy After=local-fs.target, akkor le is késtem a dologról, mert lecsatolta a fájlrendszert. No de akkor mi után? Azt egyelőre nem tudom hogy miként fedezzem fel, az egyes service folyamatok sorrendjét kikapcsolás esetén. Van erre valami lehetőség, vagy ötletek, hogy mit állítsak be?
- 595 megtekintés
Hozzászólások
amikor ráklikkelnek a Leállításra
Ha csak akkor kell, amikor ráklikkelsz a leállításra, akkor dobj egy drop-in-t a display-manager.service-re, amiben adsz egy újabb ExecStop-ot neki :)
Magyarul az ide berakott szkriptek melyeknek talán még fájlműveleteket is kellene folytatniuk, nem fognak működni, mert eddigre (addigra?) már lecsatolódott a fájlrendszer, kiléptek a felhasználók, és ennyi.
Igen, jól látod.
Jól gondolom-e hogy ez talán disztrófüggő?
Vannak standard target-ek (pl. az általad is említett local-fs.target), lásd https://www.freedesktop.org/software/systemd/man/systemd.special.html
Ha jól tippelek, neked a shutdown.target kell (lásd a fenti linken).
BlackY
"Gyakran hasznos ugyanis, ha számlálni tudjuk, hányszor futott le már egy végtelenciklus." (haroldking)
- A hozzászóláshoz be kell jelentkezni
Ok. ok. Nem voltam elég világos. Nem CSAK akkor, hanem bármikor amikor a gép leállni készül. Legyen az akár szkript által indított shutdown -h now.
Tehát van egy fájlom, melyben UTC formában időpontok lehetnek. Ebből a fájlból kinyerem az aktuális időponthoz képest a legközelebbi jövő időt. (Na ezt szépen megfogalmaztam.) S ezt átadom az rtcwake parancsnak hogy állítsa be az automatikus bekapcsolást. Ennek a szkriptnek kellene lefutnia. A szkript manuálisan meghívva működik. A hozzá készült service:
Jelenleg ez van benne:
[Unit]
Description=Wake dtvRip
DefaultDependencies=no
Before=shutdown.target
RequiresMountsFor=/home
[Service]
Type=oneshot
ExecStart=/usr/local/bin/dtvrip_poweron --stop
#RemainAfterExit=yes
[Install]
WantedBy=shutdown.target
- A hozzászóláshoz be kell jelentkezni
És ezzel leállításkor nem fut le? Journalban látszik valami róla?
BlackY
"Gyakran hasznos ugyanis, ha számlálni tudjuk, hányszor futott le már egy végtelenciklus." (haroldking)
- A hozzászóláshoz be kell jelentkezni
DE függő. KDE alatt szkriptelhető ez egészen biztos.
LXDE alatt és egyébként más DE alatt is egyszerűen cseréld le - itt kattintásról van szó, ahogyan fent írtad - az ikonhoz tartozó menü parancsát. Megnéztem, LXDE alatt "lxqt-leave --shutdown" fut le.
READY.
▓
- A hozzászóláshoz be kell jelentkezni
Nezd at a leallitas logjait:
journalctl -b -1
Nalam pl igy neznek ki a targetek:
May 22 15:24:38 eff-tp systemd[955]: Stopped target Bluetooth.
May 22 15:24:38 eff-tp systemd[955]: Stopped target Main User Target.
May 22 15:24:38 eff-tp systemd[955]: Stopped target Basic System.
May 22 15:24:38 eff-tp systemd[955]: Stopped target Paths.
May 22 15:24:38 eff-tp systemd[955]: Stopped target Sockets.
May 22 15:24:38 eff-tp systemd[955]: Stopped target Timers.
May 22 15:24:38 eff-tp systemd[955]: Reached target Shutdown.
May 22 15:24:38 eff-tp systemd[955]: Reached target Exit the Session.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Network.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Remote File Systems.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Basic System.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Paths.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Slices.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Sockets.
May 22 15:24:38 eff-tp systemd[1]: Stopped target System Initialization.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Local Encrypted Volumes.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Local File Systems.
May 22 15:24:38 eff-tp systemd[1]: Stopped target Local File Systems (Pre).
May 22 15:24:38 eff-tp systemd[1]: Stopped target Swap.
May 22 15:24:38 eff-tp systemd[1]: Reached target Unmount All Filesystems.
May 22 15:24:38 eff-tp systemd[1]: Reached target Shutdown.
May 22 15:24:38 eff-tp systemd[1]: Reached target Final Step.
May 22 15:24:38 eff-tp systemd[1]: Reached target Power-Off.
Ebbol ugye az latszik, hogy a system szintu shutdown.target az mar unmount utan van. Viszont a user szintu shutdown.target (955-os pid), az pl teljesen jo lehet.
A masik lehetoseged, hogy csinalsz egy olyan service-t, ami a Local FS utan indul el, es az ExecStop-ban van a tenyleges mukodes, ugyanis a fuggoseg miatt ezt elotte fogja leallitani:
[Unit]
Description=Wake dtvRip
After=local-fs.target
RequiresMountsFor=/home
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/usr/local/bin/dtvrip_poweron --stop
[Install]
WantedBy=multi-user.target
- A hozzászóláshoz be kell jelentkezni
Slackware alatt a /etc/rc.d/rc.6 script tartalma:
# Run any local shutdown scripts:
if [ -x /etc/rc.d/rc.local_shutdown ]; then
/etc/rc.d/rc.local_shutdown stop
fi
- A hozzászóláshoz be kell jelentkezni
Azt hiszem megvan a probléma. A gond az, hogy a lefutó szkriptben változókat használok, mert muszáj, és az útvonal is egy változó. Éppen ezért a systemd nem értelmezi.
Tesztnek kiírattam vele egy fájlba a pontos időt. Betette a gyökérbe. Utána pontosan megadtam a felhasználó egyik rejtett almappáját, és oda is betette. Ha a felhasználó ugyanezen mappája egy változóban volt, akkor már nem tette bele.
Vagyis a környezeti változók ugrottak. Úgy tűnik EnvironmentFiles használata lesz a megoldás. De ez egyelőre kínai. S ha jól értelmezem, emiatt a nagy probléma, talán a hordozhatóság lesz.
- A hozzászóláshoz be kell jelentkezni
A környezeti változókat szépen berakod egy jól irányzott fájlba - arra figyelj, hogy név=érték párosok vannak csak, behelyettesítés, mint shellben az (még) nincs - és megadod a unitban, hogy EnvironmentFile=/etc/sysconfig/sajatunitenv és ennyi. Ha a Fájl létezése nem kötelező, akkor meg EnvironmentFile=-/etc/sysconfig/sajatunitenv
- A hozzászóláshoz be kell jelentkezni
Igen. Köszi. De az csak ott lehet?
Lássuk egészben. Ahogy a bevezetőben írtam, van egy fájl időpontokkal teli. A szkript amit szándékozok lefuttatni, az a következőket teszi.
Először is megkeresi a fájlt.
wake_path=$(/usr/bin/find $HOME/ -maxdepth 3 -name "rectime.txt" -exec dirname {} \; 2>/dev/null)
wake_file="rectime.txt"
Az aktuális dátumhoz képest letörli a régieket.
awk -v _now="${actualtime}" '$1 > _now {print $1}' < "${wake_path}/${wake_file}" > /tmp/"${wake_file}"
Majd ezt a tisztított fájlt mv-vel visszateszem a helyére. Utána kiveszem az aktuális időhöz legközelebb eső időpontot amikor be kell kapcsolnia a gépnek.
nextTime=$(head -n1 < "${wake_path}/${wake_file}" | sort)
Majd az így kapott időt átadom az rtcwake-nak. Nos itt gyenge pont az az, hogy a wake_path és a wake_file a felhasználó valamelyik mappájában van. S emiatt, mivel a felhasználó bárki lehet, muszáj változóba tenni az útvonalat. Esetleg milyen más alternatívák lehetnek? /usr/local/etc/ s ide tenni a wake_filet-? Akkor lehetne abszolút útvonalat használni. S nem kell törődni a felhasználókkal, ellenben hozzáférést kell biztosítani a felhasználó részére az /usr/share/etc fájlhoz. Ha itt harapom meg itt fáj, ha ott akkor ott. Ötletek? Esetleg más megközelítés?
- A hozzászóláshoz be kell jelentkezni
Nomostan egy systemd-s unit adott user nevében (User=...) fog futni (vagy root, ha nem adod meg), tehát már a feladat megfogalmazása is erősen szuboptimális, ez az egyik. A másik, hogy nem törődik azzal, hogy "a" user bemegy, leállítás előtt bedob egy mondjuk "4 óra mulva" értéket, majd "b" user a leállított gépet elindítja 2 óra múlva, és mond egy "3 óra mulva"-t.
Nomostan a kettő közül melyik lesz az érvényes?
A wake_path önállóan sehol nincs használva, ergo kidobható. A unitból induló scriptben én végigmennék az _összes_ adott nevű fájlon (Ez jöhet env-ből, hogy mi legyen a neve, amit keres) a /home/*/ alatt, és az összes fájlból takarítanám a múltbéli időpontokat, a takarítottakat visszaraknám a helyükre _és_ összemásolnám egy temp fájlba, amiből egy jól irányzott sort -n meg head -1 kimenete az, amire szükséged van.
A /tmp/${wake_file} használata nem szép, és nem jó. Tessék az mktemp-et használni, illetve a "trap" használatát is megszokni az átmeneti állomány takarításához.
- A hozzászóláshoz be kell jelentkezni
Parancs értettem! Kérek engedélyt meghunyászkodni. Zeller őrmester elvtársnak jelentem ezt a trap nevű fickót nem ismerem. Én még csak most jöttem. Az mktemp meg kimaradáson van, és mivel nem láttam, kiment a fejemből. De ha visszajön majd beállítom a takarítók közé.
- A hozzászóláshoz be kell jelentkezni
a és b user. Értem hogy mire gondolsz, de itt nem arról van szó, hogy egy gépen 20 felhasználó, és mind beírkálnak dolgokat. Hanem ha a kész projektet megosztom a nagyérdeművel, és ki tudja ki tölti le, az ő felhasználó neveikre gondoltam. Úgy gondolom, hogy otthoni környezetben általában egy gépet, egy ember használ. Amúgy amit leírtál:
én végigmennék az _összes_ adott nevű fájlon (Ez jöhet env-ből, hogy mi legyen a neve, amit keres) a /home/*/ alatt, és az összes fájlból takarítanám a múltbéli időpontokat, a takarítottakat visszaraknám a helyükre _és_ összemásolnám egy temp fájlba, amiből egy jól irányzott sort -n meg head -1 kimenete az, amire szükséged van.
Azt hiszem ezt is csináltam.
No de ott most megakadtam, hogy megtalálja, de hogyan hivatkozik rá, ha nincs meg az útvonal? Hiszen azt mondod a wake_path-ra nincs is szükség.
find $HOME/ -maxdepth 3 -name "rectime.txt"
Ez szvsz kevés. Én nem tanultam a programozást iskolában. S lehet hogy elég. Akkor hogy hivatkozzak rá? OK, meg van a fájl. És...? S hogy tudjam hol van, ezért lett a wake_path meghatározva.
wake_path=$(/usr/bin/find $HOME/ -maxdepth 3 -name "rectime.txt" -exec dirname {} \; 2>/dev/null)
No de a systemd miatt ez az út nem lesz járható. A kérdés, amire nem kaptam választ. Az env fájl csak az /etc/sysconfig mappában lehet? Az mktempet én így tudom használni.
tmp_wake_file="$(mktemp -p /tmp)" && chmod 0700 ${tmp_wake_file}
awk -v _now="${actualtime}" '$1 > _now {print $1}' < "${wake_path}/${wake_file}" > /tmp/"${tmp_wake_file}"
Ha ez így nem jó, akkor szívesen veszem a javaslatokat.
- A hozzászóláshoz be kell jelentkezni
A "find /home -maxdepth 3 -type f -name rectime.txt" kimenetén a rectime.txt fájlok teljes útvonallal jelennek meg, minden user állományát felsorolva.
A systemd-s unitnak ezeket kell feldolgoznia a leállításkor (mindet!), hiszen nem tudhatja, hogy melyik user írt be valamit a sajátjába. Mert attól, hogy jozsika állítja le a gépet, és neki van holnaputánra egy bejegyzése, még pistike simán beírhatott a sajátjába egy holnapit úgy, hogy közben nem volt újraindítva a gép. Tehát mindenkinek a fájlját tessék feldolgozni :-)
Innentől kezdve meg minden fájllal két dolgot kell csinálni: kipucolni a múlbéli bejegyzéseket, a kipucolt fájllal felülcsapni az eredetit, majd ezt a takarított fájlt hozzáírni egy átmeneti fájlhoz, és a végén ezt a mindenki bejegyzéseit tartalmazót sort -n, és az első sorban lévő időre beállítani az ébresztést.
A trap meg legyen a barátod, ha átmeneti állományokat gyárt a scripted: a trap-ben hívott eljárásban takaríts, mert nagyon nem szép, ha ottmarad a /tmp (vagy bármi) alatt a szemét.
A systemd-s unitban megadott fájlt használja env fájlként, ha akarod, a /ide/rakom/az/env/fájlokat/mert/csak/fittyfene.env.de.a.kiterjesztés.sem.fontos.meg.lényeges állományt is megadhatod :-)
- A hozzászóláshoz be kell jelentkezni
jajjaj, systemd service vs variable substitution meg ugy egyaltalan a valtozok kezelese egy csodas dolog, sokat lehet szenvedni vele:
https://www.freedesktop.org/software/systemd/man/systemd.service.html#E…
ez meg az environment szekcio: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Envi…
Valamint kornyezeti valtozok is trukkosek, pl PATH modification: https://unix.stackexchange.com/questions/347873/set-path-for-a-systemd-…
- A hozzászóláshoz be kell jelentkezni
Nem shell scriptként kell kezelni az EnvironmentFile
tartalmát, de ennyi - meg kell szokni...
- A hozzászóláshoz be kell jelentkezni
Nos. Megoldottam, meg nem is. Első körben visszavettem az arcomból, és teljesen felhasználói szintre mentem. systemd ott is van. Némiképp módosítottam a service fájlt, és jelentem működik. DE csak egy feltétellel, ha előtte manuálisan elindítom a service-t. A gép bekapcsolása után jelenleg:
$ systemctl --user status dtvrip-wake.service
● dtvrip-wake.service - Wake dtvRip
Loaded: loaded (/home/nextra/.config/systemd/user/dtvrip-wake.service; enabled; vendor preset: enabled)
Active: inactive (dead)
Engedélyezve van, ahogy írja, és arra számítottam, hogy elindul ha itt az ideje. Persze, ha manuálisan "bestartolom", akkor minden rendben. Lefut és be is kapcsolja a gépet a megfelelő időben. Most azt keresem, hogy miként lehetne ezt a problémát megoldani.
Valahol ezt olvastam. "Alapértelmezés szerint a systemd elindítja az engedélyezett felhasználói egységeket, amikor a felhasználó bejelentkezik, és leállítja őket, miután a felhasználó kijelentkezett ." No de akkor?
A # loginctl user-status USER nem jeleníti meg ezt a service-t. Valami linger is képben lehet. Nem vagyok otthon ebben.
- A hozzászóláshoz be kell jelentkezni