У меня есть демон, реализованные в Баше и выполняются с помощью 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", целевая команда менеджера окон . Я предполагаю, что если команда windows manager работает в системе, это означает, что рабочий стол полностью загружен, и любая «графическая» команда уверена.
Где определяется переменная WM_CMD? В crontab
строке:
@reboot DISPLAY=:0 WM_CMD=/usr/bin/gnome-shell exec script_path/myscript.sh &> /dev/null
Но я также думаю, что можно было бы обнаружить «команду менеджера окон» с помощью других системных запросов. Однако для меня достаточно определения WM_CMD в файле crontab.
lightdm
Ответы:
Попробуйте использовать D-Bus для запроса информации о сеансе из
logind
сервиса. Имеетorg.freedesktop.login1.Manager
интерфейс с несколькими сигналами типаSessionNew
иSeatNew
.org.freedesktop.login1.Seat
иorg.freedesktop.login1.User
интерфейсы. Это может помочь получить состояние сеанса / места / пользователя.источник
Используйте сценарий запуска сеанса входа,
~/.xprofile
чтобы создать для вас какой-нибудь флаговый файл. Будь~/.xlogin_flag
то в другом скрипте, используйтеinotifywatch
из пакета,inotify-tools
чтобы увидеть, как он создается, трогается или удаляется.источник
Проверьте вывод
w
команды. Вы увидите тип входа (X дисплей) в поле LOGIN @.источник
Я думаю, что самый простой способ проверить, подключен ли пользователь в X11, - это проверить процессы, в которые производится запись,
$HOME/.xsession-errors
поскольку при графическом входе в систему все ваши stderr перенаправляются туда.В противном случае просто используйте
w
команду, как уже предложено @Grzegorz: еслиFROM
столбец начинается с,:
то это графическая сессия.источник
Проверьте в каталоге времени выполнения lightdm. На Arch с systemd и lightdm, когда пользователь входит в систему, создается файл xauthority.
Вы можете проверить это с помощью чего-то подобного в цикле while.
источник