我有一个守护进程,在 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
但我也认为可以通过其他系统请求来检测“Windows 管理器命令”。然而,对我来说,在 crontab 文件中定义 WM_CMD 就足够了。
答案1
logind
尝试使用D-Bus从服务中查询会话信息。它具有org.freedesktop.login1.Manager
与多种信号的接口,例如SessionNew
和SeatNew
。org.freedesktop.login1.Seat
和org.freedesktop.login1.User
接口。它可以帮助获取会话/席位/用户状态。
答案2
使用登录会话启动脚本~/.xprofile
为您创建一些标志文件。是的~/.xlogin_flag
,然后在您的其他脚本中使用inotifywatch
from packageinotify-tools
来查看它的创建、触摸或删除。
答案3
检查w
命令的输出。您将在 LOGIN@ 字段中看到登录类型(X 显示)。
答案4
检查 lightdm 的运行时目录。在带有 systemd 和 lightdm 的 Arch 上,当用户登录时,会创建一个 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