Witam szerokie grono,
W momencie uruchamiania systemu, pewna usługa uruchamia prosty skrypt, który z kolei odtwarza wybrany przeze mnie dźwięk.
Skrypt wygląda następująco:
#!/bin/bash
sleep 4;
aplay /home/groovy/login.wav
Usługa uruchamia skrypt, ten czeka 4 sekundy i odtwarza dźwięk. U mnie trafia to na moment pojawienia się pulpitu.
Problem polega na tym, że nie podoba mi się fragment kodu z komendą sleep. Jest nieelegancki.
Najlepiej byłoby gdyby poprzez instrukcję until/do/done sprawdzał czy pulpit jest uruchomiony. Jeśli nie to niech czeka tak długo aż się załaduje.
#!/bin/bash
until [[ $(systemctl status gdm.service | grep "active") != active ]];
do
sleep 1;
done
aplay /home/groovy/login.wav
Powyższy kod nie działa, ponieważ gdm.service ładuje się wcześniej, odtwarza dźwięk ale pulpit pojawia się po około 4 sekundach.
Jak ustawić warunek until aby sprawdzał czy wyświetlony jest już pulpit lub ekran logowania?
U mnie na xfce4 mam dźwięk powitalny, i używam takiego skryptu
#!/bin/bash
sleep 15s
canberra-gtk-play -f /home/robson/.canberra/logowanie.wav
exit 0
A wartość sleep jest taka, bo najpierw musi się załadować pulpit.
EDIT.
Oczywiście aby skrypt działał, trzeba mu nadać prawa wykonywalności jako program.
Ale z tego co wiem, gdm i tak się uruchamia tyle, że po prostu loguje automatycznie i nie pokazuje tego na ekranie.
To prawda. Pomija proces logowania i uruchamia środowisko graficzne.
Gdybyś miał kilka zainstalowanych środowisk graficznych i włączone logowanie się,
to właśnie z niego możesz wybrać środowisko.
To nie może odbywać się losowo ponieważ często jedna usługa jest zależna od innej. Np. właśnie załadowanie pulpitu jest zależne od gdm, którzy przecież musi załadować się pierwszy.
Napisałem " W systemd większość usług jest uruchamiana losowo. "
Są pewne wyjątki w systemd.
Natomiast środowisko graficzne nie jest uruchamiane przez systemd, a przez display menadżera np. gdm, lightdm , itd.
Także jeśli uparcie chcesz sprawdzić czy środowisko się uruchomiło,
to chyba najlepiej spytać się developerów środowiska którego używasz.
Przykładowo mógłbym sprawdzać czy powstał już proces środowiska graficznego.
U mnie to jest " mate-session " ,
ten fragment drzewa po uruchomieniu komendy pstree ( wyświetla drzewo procesów )
├─lightdm─┬─Xorg───{Xorg}
│ ├─lightdm─┬─mate-session─┬─caja───4*[{caja}]
Tylko że sprawdzanie co sekundę czy proces już istnieje, to zjada zasoby komputera.
Trochę jak odliczanie sleep.
Powinno się używać inotifywait, ale na razie to działa tylko na plikach i folderach.
Jeśli założymy, że plik $HOME/.xsession-errors powstaje po uruchomieniu się środowiska,
to można by go obserwować czy się zmienił , np.
#!/bin/bash
inotifywait -q -e modify,delete_self,move_self /home/nazwa_uzytkownika/.xsession-errors &>/dev/null
aplay /home/groovy/login.wav
Ale czy on rzeczywiście powstaje po, tego nie wiem. Możesz sprawdzić.
Druga sprawa to tego dźwięku, ale też byś musiał sprawdzić.
U mnie odnośnie tego dźwięku pierw powinna wystartować alsa, a później pulseaudio ( ponieważ pulseaudio jest nakładką na alsę )
W systemd znalazłem tylko
$ systemd-analyze blame | grep alsa
59ms alsa-restore.service
Nie jestem pewien czy to uruchamia alsę.
Natomiast pulse audio startuje wraz ze środowiskiem graficznym,
czyli w moim przypadku środowisko uruchamia skrypt z /etc/xdg/autostart/pulseaudio.desktop
( Podałem wyżej link to XDG Autostart )
Które pierwsze się uruchomi?
Środowisko graficzne, czy Pulseaudio?
W sumie to nie istotne, zawsze możesz sprawdzić oba procesy.
Czy dzwięk również zadziała, gdy Alsa się uruchomiła, ale Pulse Audio jeszcze nie ?
Pozostawię Tobie to do sprawdzenia.
Pobawiłem się jeszcze trochę. ( Ubuntu Mate 22.04 )
Wnioski:
1. Wiadomo skrypt uruchomiony z " XDG Autostart " działa.
2. Cron
2.1. Cron z konta root, tam dźwięku z konta root (mam na myśli sudo) nie udało mi się uruchomić.
cvlc nawet informuje że z konta root nie będzie działał ponieważ jest to nie polecane ze względów bezpieczeństwa.
( Oczywiście po przekierowaniu wyjścia komendy do pliku z logiem )
Po za tym sam skrypt bash powinien uruchomić się.
Natomiast notify-send moze wymagać dodania zmiennych
export DISPLAY=:0.0 && export XAUTHORITY=/home/twoja_nazwa_uzytkownika/.Xauthority
2.2. Cron z konta użytkownika, tutaj dźwięk udało mi się uruchomić,
ale wymaga dodania zmiennych " export XDG_RUNTIME_DIR="/run/user/1000" && export DISPLAY=:0.0 && "
Z czego zmienna środowiskowa XDG_RUNTIME_DIR jest potrzebna do odtwarzania dźwięku https://wiki.archlinux.org/title/PulseAudio#Play_sound_from_a_non-interactive_shell_(systemd_service,_cron)
Mój wpis w cronie wygląda tak
@reboot export XDG_RUNTIME_DIR="/run/user/1000" && export DISPLAY=:0.0 && $(bash /home/moja_nazwa__uzytkownika/Pulpit/test/Welkom2.bash)
Przykład wygląda tak ( Oczywiście musiałem wcześniej doinstalować pakiet inotify-tools )
#!/bin/bash
inotifywait -q -e modify,delete_self,move_self /home/moja_nazwa__uzytkownika/.xsession-errors &>/dev/null
/usr/bin/canberra-gtk-play -i service-login
/usr/bin/notify-send -u normal -i "info" 'Boss !!' 'To jest test ze skryptu'
Jednak mam wątpliwości czy warto używać inotifywait w tym przypadku, ponieważ:
systemy zazwyczaj ładują się dość szybko, a inotifywait nie jest częścią bash i uruchamiając się też zużywa zasoby.
Inotifywait się lepiej sprawdza gdy jest duży czas oczekiwania.
Drugi sposób / przykład o którym wspominałem
#!/bin/bash
until pidof pulseaudio && pidof mate-session ; do
sleep 1
done
/usr/bin/canberra-gtk-play -i service-login
/usr/bin/notify-send -u normal -i "info" 'Boss !!' 'To jest test ze skryptu'
Także widzisz, nawet tutaj musiałem użyć komendy sleep.
Jedyna różnica to taka, że pętla się wykonuje tak długo aż oba procesy będą uruchomione.
Mimo wszystko dla każdego przykładu u siebie dodatkowo dałbym 1 sekundę opóźnienia
przed wykonaniem dźwięku dla lepszego efektu,
ponieważ dźwięk u mnie minimalnie pojawia się wcześniej niż pulpit.