
У меня есть демон, реализованный в bash и работающий с помощью cron
и @reboot
опции, который показывает рабочий стол в состоянии бездействия. Скрипт выглядит следующим образом (тайминги короткие для целей тестирования):
#!/bin/bash
P_STATE=0
while :
do
sleep 5
if [ $P_STATE == 0 ]; then
[ `xprintidle` -ge 25000 ] && P_STATE=1 && wmctrl -k on
else
[ `xprintidle` -le 25000 ] && P_STATE=0
done
Проблема: Если пользователь все еще находится, например, на экране входа в систему xprintidle
и wmctrl
терпит неудачу, так как рабочий стол еще не загружен. Чтобы избежать этого, я поместил следующие строки в самом начале скрипта:
while:
do
sleep 10s
[ -n `who | grep "$USER"` ] && break
done
Итак, скрипт ждет, пока пользователь (переменная USER установлена на мое имя пользователя в файле crontab) войдет в систему. Но если пользователь начинает, например, терминальный сеанс (а не графический сеанс, как KDE или GNOME), скрипт также продолжит работу.
Как определить, находится ли пользователь уже в "графическом" сеансе, способном "показывать режим рабочего стола" или нет? И, кроме того, как убедиться, что "графический" сеанс полностью загружен, а не находится в процессе загрузки или что-то в этом роде?
Мое решение:
Мое (неформальное) решение — добавить в основной цикл grep
строку:
WAIT_TIME=180
while:
do
sleep $WAIT_TIME
[ ! -n "`ps -ef | grep "$WM_CMD" | grep -v "grep"`" ] && continue
## My actions here
done
Целью является "$WM_CMD"команда диспетчера окон. Я предполагаю, что есликоманда диспетчера оконзапущен в системе, это означает, что рабочий стол полностью загружен и любая «графическая» команда выполняется наверняка.
Где определена переменная WM_CMD? В crontab
строке:
@reboot DISPLAY=:0 WM_CMD=/usr/bin/gnome-shell exec script_path/myscript.sh &> /dev/null
Но я также думаю, что можно было бы обнаружить "команду менеджера окон" с помощью других системных запросов. Однако для меня достаточно определить WM_CMD в файле crontab.
решение1
Попробуйте использовать D-Bus для запроса информации о сеансе из logind
сервиса. Он имеет org.freedesktop.login1.Manager
интерфейс с несколькими сигнальными интерфейсами, такими как SessionNew
и SeatNew
. org.freedesktop.login1.Seat
и org.freedesktop.login1.User
интерфейсами. Он может помочь получить состояние сеанса/места/пользователя.
решение2
Используйте сценарий запуска сеанса входа ~/.xprofile
, чтобы создать для вас файл флага. Будь то ~/.xlogin_flag
, тогда в вашем другом сценарии используйте inotifywatch
from package, inotify-tools
чтобы увидеть, как он создается, трогается или удаляется.
решение3
Проверьте вывод w
команды. Вы увидите тип входа (отображение X) в поле LOGIN@.
решение4
Проверьте каталог выполнения lightdm. В Arch с systemd и lightdm, когда пользователь входит в систему, создается файл xauthority.
$ whoami
carl
$ sudo ls -al /run/lightdm/carl
total 4
drwx------ 2 carl carl 60 Dec 11 19:40 .
drwx--x--x 8 lightdm lightdm 160 Dec 11 19:40 ..
-rw------- 1 carl carl 55 Dec 11 19:40 xauthority
Вы можете проверить это с помощью чего-то вроде этого в цикле while.
[[ -f /run/lightdm/${USER}/xauthority ]] && continue