У меня есть демон, реализованные в Баше и выполняются с помощью 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