Ubuntu Suomen keskustelualueet

Ubuntun käyttö => Ubuntu tietokoneissa => Aiheen aloitti: AimoE - 09.04.17 - klo:14.18

Otsikko: Koneen herätessä suoritettava komento käyttäjän kontekstissa? [RATKAISTU]
Kirjoitti: AimoE - 09.04.17 - klo:14.18
tamrockin kysymys (https://forum.ubuntu-fi.org/index.php?topic=52051.msg398631#msg398631):

Onkos olemassa muuta konstia, jolla varmuuskopioinnin saisi tehtyä? Esim automaattisesti vaikka koneelle kirjautumisen yhteydessä?

herätti pohtimaan muitakin vaihtoehtoja kuin Käynnistettävät ohjelmat -asetustyökalu, johon nm viittaa ja jota olen itsekin käyttänyt.

Ask Ubuntu -artikkeli Run Script on Wakeup? (http://askubuntu.com/questions/226278/run-script-on-wakeup) kertoo että suspend-tilasta herätessä suoritettavat komentojonot on pantava hakemistoon /lib/systemd/system-sleep/, ja sieltä löytyykin hyvä malli:

Koodia: [Valitse]
$ ls /lib/systemd/system-sleep/
hdparm         wpasupplicant 
$ cat /lib/systemd/system-sleep/wpasupplicant
#!/bin/sh
set -e

if [ "$2" = "suspend" ] || [ "$2" = "hybrid-sleep" ]; then
    case "$1" in
        pre) /sbin/wpa_cli suspend ;;
        post) /sbin/wpa_cli resume ;;
    esac
fi

mutta tämä suoritetaan järjestelmänlaajuisesti.

Niinpä herää kysymys mikä on hakemiston ~/.config/upstart tarkoitus? Hakemisto ~/.config/autostart sisältää niiden ohjelmien käynnistimet jotka suoritetaan sisään kirjautuessa. Kokeilin toimiiko ~/.config/upstart samalla tavalla, eikä se toimi. Onko se dokumentoitu jossain?

Jos se ei ole se mitä haen, niin millä keinolla voi suorittaa jotain aina koneen herätessä ilman systeemin oikeuksia, ihan käyttäjän omassa kontekstissa?
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: nm - 09.04.17 - klo:18.21
Niinpä herää kysymys mikä on hakemiston ~/.config/upstart tarkoitus?

Se on Upstartin Session Init (http://upstart.ubuntu.com/cookbook/#session-init) -mekanismin skriptihakemisto. En tiedä, onko ominaisuus enää käytössä enää 16.04:ssä Systemd:n syrjäytettyä Upstartin.


Jos se ei ole se mitä haen, niin millä keinolla voi suorittaa jotain aina koneen herätessä ilman systeemin oikeuksia, ihan käyttäjän omassa kontekstissa?

Voit siirtyä tietyn käyttäjän kontekstiin sudolla. Aseta myös DISPLAY-muuttuja, jos on tarkoitus ajaa graafisia ohjelmia. Jos haluat, että skripti ajetaan kaikille kirjautuneille käyttäjille, tunnukset pitänee onkia prosessilistoista: http://unix.stackexchange.com/questions/117083/how-to-get-the-list-of-all-active-x-sessions-and-owners-of-them


Vaihtoehtoinen ratkaisu voisi olla dbus-viestien tarkkailu. Sieltä ehkä saa tiedon heräämisestä. Ainakin lukituksen avaaminen antaa signaalin: http://askubuntu.com/questions/204073/how-to-run-script-after-resume-and-after-unlocking-screen/882585#882585
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: Tomin - 09.04.17 - klo:18.30
Luultavasti noita voisi tehdä jotenkin systemd:n avulla, sillä se tarjoaa myös käyttäjän palvelut ja istunnonhallinnan (logind).
Tuolla näyttää olevan kaikenlaista hyödyllistä, kuten käyttäjän unit-tiedostojen sijainnit: https://wiki.archlinux.org/index.php/Systemd/User
Systemd pystyy suorittamaan unit-tiedostoja koneen palatessa valmiustilasta: https://unix.stackexchange.com/questions/124212/writing-a-systemd-service-to-be-executed-at-resume

Muokkaus: Jaha, ideani ei olekaan ihan niin hyvä kuin toivoin. Käyttäjäkohtaiset unit-tiedostot eivät voi riippua järjestelmänlaajuisista, joten tuo alempi ei onnistu ihan niin helposti kuin ajattelin.
https://unix.stackexchange.com/questions/149959/how-to-run-systemd-user-service-to-trigger-on-sleep-aka-suspend-hibernate
Lainaus
And unfortunately the 'user' instances currently have no way to depend on systemwide services.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 09.04.17 - klo:20.43
Voit siirtyä tietyn käyttäjän kontekstiin sudolla. Aseta myös DISPLAY-muuttuja, jos on tarkoitus ajaa graafisia ohjelmia.

Täytyypä ryhtyä selvittämään tätä vaihtoehtoa.

Vaihtoehtoinen ratkaisu voisi olla dbus-viestien tarkkailu. Sieltä ehkä saa tiedon heräämisestä. Ainakin lukituksen avaaminen antaa signaalin: http://askubuntu.com/questions/204073/how-to-run-script-after-resume-and-after-unlocking-screen/882585#882585

Tämä olisi ihan käypänen jos pystyisin erottamaan onko kyse suspendista herääminen vaiko pelkkä lukituksen avaus. Käykin ilmi (http://serverfault.com/questions/573379/system-suspend-dbus-upower-signals-are-not-seen) että DBus ei enää lähetä signaalia resume-vaiheesta, koska sen käsittelee nykyään systemd ja DBus:n sijaan pitäisikin lukea logind:n signaaleja. Hieno juttu, koodimallit ja kaikki. Mutta kun en ole koskaan opetellut Pythonia, niin nyt on tenkkapoo että miten toi tehdään jollain tutummalla kielellä.

Sudotttelukaan ei oikein houkuttele.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 09.04.17 - klo:21.40
Siirryin opiskelemaan miten systed:n unit-tiedostoja kirjoitetaan käyttäjän ~/config/systemd/user -hakemistoon, mutta siinäkin näköjään riittää opiskeltavaa.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 10.04.17 - klo:15.01
Olen nyt tehnyt nämä vaiheet:

Kirjoita tiedosto ~/.config/systemd/user/act_on_resume.service :

Koodia: [Valitse]
[Unit]
After=suspend.target

[Service]
Environment=DISPLAY=:0
#ExecStart=/usr/bin/notify-send "%n" "Hello World"
ExecStart=/usr/local/bin/act_on_resume

[Install]
WantedBy=sleep.target

Kirjoita tiedosto /usr/local/bin/act_on_resume :

Koodia: [Valitse]
#!/bin/sh
me=$(basename $0)
notify-send "$me" "Hello World"
env > $me.log

Suorita
Koodia: [Valitse]
$ systemctl --user enable act_on_resume
Created symlink from /home/haltia/.config/systemd/user/sleep.target.wants/act_on_resume.service to /home/haltia/.config/systemd/user/act_on_resume.service.

Komentoa
Koodia: [Valitse]
loginctl enable-linger $USER en nähnyt tarpeelliseksi, koska olen tekemässä palvelua joka pyörähtää koneen herätessä ja pysähtyy pian.

Suorita
Koodia: [Valitse]
systemctl --user start act_on_resumeSuorituksen tuloksena syntyy lokitiedosto ~/act_on_resume.log, mutta notify-send  -komento menee jotenkin harakoille. Lokitiedosto näyttää samat muuttuvat ja arvot kuin komento
Koodia: [Valitse]
systemctl --user show-environment plus kaksi muuttujaa lisää (DISPLAY ja MANAGERPID).

Aseta kone valmiustilaan ja herätä. Nyt ei synny edes lokitiedostoa, saati että notify-send  -komento kertoisi jotain.

Kaikesta debuggaamisesta huolimatta en vaan keksi
* mihin joutuu notify-send -komennon tulostus, ja
* mikä on pielessä kun suoritusta ei tapahdu valmiustilasta palatessa.
En ole löytänyt lisätietoa syslogista, enkä keksi mistä muusta lokista pitäisi etsiä.

Lähteinä olen käyttänyt satunnaisten sivujen lisäksi:
http://manpages.ubuntu.com/manpages/xenial/man1/systemctl.1.html
http://manpages.ubuntu.com/manpages/xenial/man5/systemd.unit.5.html
http://manpages.ubuntu.com/manpages/xenial/man5/systemd.service.5.html

Käyttämättä ovat toistaiseksi jääneet:
http://manpages.ubuntu.com/manpages/xenial/man5/systemd-user.conf.5.html (tulee ehkä tarpeesen myöhemmin)
https://wiki.ubuntu.com/SystemdForUpstartUsers (koska en ole upstarttia koskaan käyttänytkään)
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: raimo - 10.04.17 - klo:15.16
notify-send osalta kokeile  /usr/local/bin/act_on_resume tiedoston alkuun tätä:
Koodia: [Valitse]
export DISPLAY=:0
Oikea arvo kannattaa tarkistaa komennolla
Koodia: [Valitse]
echo $DISPLAYyleensähän se on :0
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 10.04.17 - klo:15.24
notify-send osalta kokeile  /usr/local/bin/act_on_resume tiedoston alkuun tätä:
Koodia: [Valitse]
export DISPLAY=:0
Oikea arvo kannattaa tarkistaa komennolla
Koodia: [Valitse]
echo $DISPLAYyleensähän se on :0

Arvo on jo oikein siinä lokitiedostossa jonka skripti tulostaa.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: nm - 10.04.17 - klo:15.26
Koodia: [Valitse]
[Unit]
After=suspend.target

[Service]
Environment=DISPLAY=:0
#ExecStart=/usr/bin/notify-send "%n" "Hello World"
ExecStart=/usr/local/bin/act_on_resume

[Install]
WantedBy=sleep.target

Tomin linkkaamassa Stackexchange-keskustelussahan todettiin, ettei homma toimi user-puolella noilla targeteilla: http://unix.stackexchange.com/a/174837
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 10.04.17 - klo:16.25
Tomin linkkaamassa Stackexchange-keskustelussahan todettiin, ettei homma toimi user-puolella noilla targeteilla: http://unix.stackexchange.com/a/174837
Okei, luin niin paljon sivustoja peräkkäin että ihan kaikki ei pysynyt päässä oikeassa järjestyksessä.

Muokkasin nyt .service-tiedoston muotoon:

Koodia: [Valitse]
[Unit]
After=suspend.target

[Service]
User=%I
WorkingDirectory=/home/%I
Environment=DISPLAY=:0
#ExecStart=/usr/bin/notify-send "%n" "Hello World"
ExecStart=/usr/local/bin/act_on_resume

[Install]
WantedBy=sleep.target

ja sitten kopioin tiedoston hakemistoon /lib/systemd/system nimellä resume@.service. Huomaa @-merkki jota ei aikaisemmin ollut.

Suoritin sitten komennot

Koodia: [Valitse]
systemctl --user disable act_on_resume
sudo systemctl enable resume@haltia.service

-- ja aina kun joudun editoimaan tiedostoa, suoritan
Koodia: [Valitse]
sudo systemctl --system daemon-reload
Nyt kun kone herää valmiustilasta, löydän uuden lokitiedoston, ja mikä parasta, se on mun oman tunnuksen omistuksessa, ei rootin.

Jäljellä on notify-send, joka ei saa mitään näkyvää aikaan.

Ohjelmat joita oikeasti haluan ajaa ovat graafisia.

Muoks: Tuo @-jutuke löytyi täältä: https://crocodile.is/blog/2013/04/28/user-suspendresume-service-scripts-for-systemd/
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: nm - 10.04.17 - klo:17.10
Jäljellä on notify-send, joka ei saa mitään näkyvää aikaan.

Ohjaa notify-sendin stdout ja stderr johonkin lokiin. Siellä saattaa näkyä jotain virhettä.

Veikkaan, että skripti ajetaan nyt ennen valmiustilaan siirtymistä, koska sleep.target suoritetaan silloin. Joudut lisäämään skriptin alkuun parin sekunnin sleepin, jos haluat suorittaa sen vasta valmiustilasta palatessa. Jos näyttö on silloin lukittu, notify-send ei ehkä tee mitään.

Kannattaa kokeilla notify-sendin sijaan myös jotain tavallista työpöytäohjelmaa.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 10.04.17 - klo:17.33
Ohjaa notify-sendin stdout ja stderr johonkin lokiin. Siellä saattaa näkyä jotain virhettä.

Ei anna mitään tulostusta, pelkän tyhjän tiedoston:

Koodia: [Valitse]
notify-send "$me" "Hello World" 2>&1 1>act_on_resume_error.log

Veikkaan, että skripti ajetaan nyt ennen valmiustilaan siirtymistä, koska sleep.target suoritetaan silloin. Joudut lisäämään skriptin alkuun parin sekunnin sleepin, jos haluat suorittaa sen vasta valmiustilasta palatessa. Jos näyttö on silloin lukittu, notify-send ei ehkä tee mitään.

Kannattaa kokeilla notify-sendin sijaan myös jotain tavallista työpöytäohjelmaa.

Alussa oleva After-määritys nimenomaan vaatii että suoritetaan suspendin jälkeen, ei ennen sitä. Sleeppiä olen yrittänyt lisätä moneen kertaan, eikä siitä ole ollut apua.

Kokeilin vaihtaa tilalle toisen ohjelman (update-manager), ja se käynnistyi ilman sleeppiäkin. Sen kanssa tuleekin sitten ihan uusi ongelma: Vaikka käynnistys on ihan sama kuin käynnistinpalkin tai Dashin kautta, niin silti tätä kautta käynnistettynä se valittaa että mulla ei ole tarvittavia oikeuksia. Se pitäisikin siis ajaa roottina. Deja-dup-preferences myöskin käynnistyy ilman ongelmia, mutta sitä en halua koskaan ajaa heti heräämisen jälkeen. Toi update-manager saattaisi olla sellainen jonka haluaa ajaa.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 11.04.17 - klo:14.24
Myöskin notify-send -ongelma on nyt ratkaistu, se alkoi toimia kun boottasin koneen. En yhtään tiedä miksi, mutta näin vaan kävi.

Lisäksi, luettuani lisää (mm. sivua https://wiki.archlinux.org/index.php/Systemd), minun ilmeisesti kannattaisi siirtää unit-tiedosto hakemistosta /lib/systemd/system/ hakemistoon /etc/systemd/system/ noin niin kuin täydellisyyden nimissä.
Otsikko: Vs: Koneen herätessä suoritettava komento käyttäjän kontekstissa?
Kirjoitti: AimoE - 12.04.17 - klo:22.24
Myöskin notify-send -ongelma on nyt ratkaistu, se alkoi toimia kun boottasin koneen. En yhtään tiedä miksi, mutta näin vaan kävi.

Eipäs ollutkaan kyse rebootista vaan siitä että olin lisännyt skriptiin muita komentoja. Kun otin ne pois, notify-send lakkasi näkymästä. Kun lisäsin sleepin notify-sendin jälkeen, nootti tuli taas näkyviin. Kylläpä meni aikaa hukkaan tuota pähkäillessä, mutta selvisihän se lopulta.