«««

30 września 2010

Zamknij drzwi za sobą

Przyszła mi dzisiaj potrzeba zrobić coś w nijakim czasie. Czas był tak nijaki, że się tylko na moment zamykania systemu nadawał. Chciałem dodać jakiś GUI, więc musiało to się odbywać przy wylogowywaniu z GNOME.
Pierwszy pomysł był na skróty. Wystarczy napisać skrypt z listą co ma się wykonać, a na końcu dodać:

gnome-session-save --logout-dialog
Drugi nie był lepszy i różnił się tylko tym, żeby skorzystać z d-bus. Poszukiwałem jednak przeznaczonego do tego miejsca.

Jeśli korzystamy z menadżera logowania GDM (domyślny dla GNOME, często domyślny również dla XFCE itp.) możemy skorzystać z pliku: /etc/gdm/PostSession/Default, który jest wykonywany jako root po zakończeniu sesji, ale zmienne środowiskowe ustawione są na użytkownika. Jest też pewna niejasność w dokumentacji. Teoretycznie X-y są w tym momencie zatrzymywane i może dojść do pewnych błędów w działaniu graficznych aplikacji. W praktyce okna straciły obramowanie (metacity), ale wszystko działa. W normalnej pracy przy wylogowaniu wszystkie otwarte okna są ubijane. Skrypt "PostSession" uruchamia się przed masakrą okien, ale już po usunięciu obramowania (to tak, żeby nie było zdziwienia).

Aby umożliwić każdemu użytkownikowi stworzenie własnego skryptu wylogowania, wystarczy w pliku /etc/gdm/PostSession/Default umieścić:

#!/bin/sh

if [ -f ~/.post_session ] ; then
    su -l $USER -c '/bin/bash ~/.post_session'
fi

exit 0
Teraz każdy użytkownik może utworzyć skrypt bash ~/.post_session, który wykona się przy wyjściu.

Spójrzmy jeszcze na sam skrypt. Przydałoby się widzieć, co się dzieje przy jego wykonywaniu. Najprościej będzie przekierować wyjście skryptu do pliku:

exec &> ~/.post_session.log
lub osobno błędy i standardowe wyjście
exec 1> ~/.post_session.log
exec 2> ~/.post_session.error
Jednak kiedy testujemy skrypt, wolelibyśmy widzieć wyjście zwyczajnie w terminalu. Można dodać jeszcze jeden trik i przekierowanie nastąpi tylko jeśli skrypt uruchomiony jest poza terminalem.
if ! tty -s ; then
    exec &> ~/.post_session.log
fi

No dobrze, ale do czego to się może przydać? Mam np. głupi zwyczaj zapominania, że jakaś maszynka wirtualna jest włączona i chciałbym, aby przy wyjściu były wszystkie usypiane. Tak mniej więcej wygląda kod do masowego usypiania:

for v in $(VBoxManage -q list runningvms | cut -d'"' -f2) ; do
    VBoxManage -q controlvm "$v" savestate
done
Dodajmy jeszcze trochę kosmetyki. Przydałby się pasek postępu zenity i ostatecznie skrypt ~/.post_session wygląda tak:
#!/bin/bash

# post_session

# przekieruj wyjście do logu, jeśli nie uruchomiono z terminala
if ! tty -s ; then
    exec &> ~/.post_session.log
fi

# pasek postępu, czyta z deskryptora 4
exec 4> >(zenity --progress --pulsate --width=300 --auto-close --auto-kill )

echo "# zamykanie systemów wirtualnych ..." >&4
for v in $(VBoxManage -q list runningvms | cut -d'"' -f2) ; do
    VBoxManage -q controlvm "$v" savestate
done

echo "100" >&4   # zamknięcie paska
exec 4>&-        # zamknięcie deskryptora

Mam nadzieję, że nikogo nie zanudziłem i ktoś dotarł do końca, a jeszcze jak się komuś przyda to hu! hu! :)

Brak komentarzy: