我的问题是如何在 shell 上获取当前正在使用 Linux 桌面的用户名(在“普通”桌面系统上,您通常只有一个活动用户,即这里没有服务器系统,而只是您常用的笔记本电脑等) .)。如果你真的想想象一个服务器系统,我可以列出所有积极的用户。
因此,以脚本作为 cron 作业(或类似作业)作为 root 运行的情况为例,我想获取系统上当前/所有活动的用户。
我知道我可以使用w
orwho
或users
来获取当前登录的用户。没关系,但是该用户已登录并不意味着他们当前实际上是使用桌面,因为在我知道的所有桌面环境中,用户可以在登录后切换到另一个用户。
我也可以用来last
获取最后登录的用户,但这也不能保证该用户仍然是活动用户。
那么如何才能做到这一点呢?为不同的桌面环境(GNOME,KDE,...)提供特定的解决方案是可以的,但是,当然,交叉兼容的解决方案是首选。
答案1
在许多当前的发行版中,登录会话(图形和非图形)由logind
.您可以使用列出会话
loginctl list-sessions
然后使用显示每个会话的属性
loginctl show-session ${SESSIONID}
或者
loginctl session-status ${SESSIONID}
(${SESSIONID}
酌情更换);这两个变体之间的区别在于,它show-session
被设计为易于解析,session-status
是为人类消费而设计的。活动会话由其状态来标识;您可以直接使用查询
loginctl show-session -p State ${SESSIONID}
这将输出
State=active
对于活动会话。完整的show-session
输出将告诉您哪个用户已连接、正在使用哪个 TTY、是否是远程会话、是否是图形会话等。
请注意logind
,如果系统配置了多个席位,或者存在远程会话,则可以有多个活动会话。
把这一切放在一起,
for sessionid in $(loginctl list-sessions --no-legend | awk '{ print $1 }')
do loginctl show-session -p Id -p Name -p User -p State -p Type -p Remote $sessionid
done
将提供您需要的所有信息,以确定哪些会话处于活动状态以及谁正在使用它们,并且
for sessionid in $(loginctl list-sessions --no-legend | awk '{ print $1 }')
do loginctl show-session -p Id -p Name -p User -p State -p Type -p Remote $sessionid | sort
done |
awk -F= '/Name/ { name = $2 } /User/ { user = $2 } /State/ { state = $2 } /Type/ { type = $2 } /Remote/ { remote = $2 } /User/ && remote == "no" && state == "active" && (type == "x11" || type == "wayland") { print user, name }'
将通过图形会话打印所有活动用户的标识符和登录信息。
该LockedHint
属性现在指示给定会话是否被锁定,因此
for sessionid in $(loginctl list-sessions --no-legend | awk '{ print $1 }')
do loginctl show-session -p Id -p Name -p User -p State -p Type -p Remote -p LockedHint $sessionid | sort
done |
awk -F= '/Name/ { name = $2 } /User/ { user = $2 } /State/ { state = $2 } /Type/ { type = $2 } /Remote/ { remote = $2 } /LockedHint/ { locked = $2 } /User/ && remote == "no" && state == "active" && (type == "x11" || type == "wayland") { print user, name, locked == "yes" ? "locked" : "unlocked" }'
还将指示活动会话是否被锁定。
答案2
我正在使用如下所示的 bash 函数
function Xowner() {
for pid in $(ps -houid --ppid $(ps -hoppid $(pgrep X))) ; do
[ "$pid" = "0" ] && continue
id -n -u $pid
break
done
}
该函数的目的基本上是选择 Xserver 的同级进程的“第一个”非根 UID。man ps
详情请参阅。我想,如果您的用例可能涉及多个 X 服务器,您将需要更好地关注从哪一个开始。