如何找出当前(活动)XServer DISPLAY 编号?

Gey*_*Bem 8 linux arch-linux x11 gdm systemd

我正在使用 Arch Linux,当您尝试发现当前的 Xorg DISPLAY(不是通过 env 变量)时,事情并不那么容易。

这是一个工作示例:

$ cat /sys/class/tty/tty0/active
tty2

who | awk -v term="tty2" '/\(:/ $0 ~ term { gsub(/\(|\)/, "", $0); print $5 }'
:0
Run Code Online (Sandbox Code Playgroud)

这在某些情况下有效,在其他情况下则无效:

$ cat /sys/class/tty/tty0/active
tty3

who | awk -v term="`cat /sys/class/tty/tty0/active`" '/\(:/ $0 ~ term { gsub(/\(|\)/, "", $0); print $5 }'
NOTHING
Run Code Online (Sandbox Code Playgroud)

原因:

$ who
uzumaki  tty2         2015-05-16 10:50 (:0)
guest    pts/2        2015-05-16 11:47 (:1)
uzumaki  tty4         2015-05-16 11:07
Run Code Online (Sandbox Code Playgroud)

来宾用户 (tty3) 使用 pts(伪终端)启动了他的会话。

我正在使用 gdm 并且它在没有特定命令的情况下启动 xorg 服务器(未阐明显示编号)。

$ ps au | grep -e Xorg -e vt
uzumaki    788  1.4  0.9 740464 150672 tty2    Sl+  10:50   5:38 /usr/lib/xorg-server/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -verbose 3
guest     1062  0.0  0.1 465748 32344 tty3     Sl+  10:51   0:19 /usr/lib/xorg-server/Xorg vt3 -displayfd 3 -auth /run/user/1002/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -verbose 3
Run Code Online (Sandbox Code Playgroud)

所以百万的问题是:如何找出当前(正在使用的)XServer DISPLAY 号?当前,如上所述,我们可以拥有多个服务器(多个用户)。

int*_*lfx 7

您可以尝试使用loginctl list-sessions获取会话列表,然后loginctl show-session -p Display -p Active <session ID>在其中的每一个上使用以获取与当前活动会话关联的 X11 显示编号。

像这样(在 bash 中):

TARGET_DISPLAY=()
while read id uid user seat; do
    while IFS='=' read property value; do
        case "$property" in
        Active)
            if [[ "$value" != "yes" ]]; then continue; fi
            ;;
        Display)
            if [[ "$value" ]]; then
                TARGET_DISPLAY+=( "$value" )
            fi
            # else the session isn't graphical
            ;;
        esac
    done < <(loginctl show-session -p Display -p Active "$id")
done < <(loginctl list-sessions --no-legend)
Run Code Online (Sandbox Code Playgroud)

$TARGET_DISPLAY是一个数组,因为假设可能有多个活动会话(在多席位系统上)。如果这在您的配置中是不可能的,您可以将其设置为一个简单的变量并break 2在赋值后添加一条语句以退出两个循环。

然而...

...这不再适用于 GDM,因为在这种情况下,X 服务器在会话启动(具有用户权限)并且/usr/bin/gdm-x-session不会将此信息传达回logind(由于缺少 API)。

在其他情况下(当 X 服务器在会话创建之前由 DM 启动时)这很可能会起作用。我不知道任何其他方法,抱歉。


Gey*_*Bem 5

嗯,目前我的意思是 XOrg 服务器的主动显示。请记住,我们可以运行多个 XOrg 服务器,并且它们可以是多头的,这使得事情更难操作。

另一个重要的注意事项是,在某些情况下无法访问 DISPLAY 变量(例如 systemd)。

经过在commandlinefu中的一些讨论,我得到了这个结果:

for p in $(pgrep -t $(cat /sys/class/tty/tty0/active));
do 
    d=$(awk -v RS='\0' -F= '$1=="DISPLAY" {print $2}' /proc/$p/environ 2>/dev/null); 
    [[ -n $d ]] && break; 
done;
echo $d
Run Code Online (Sandbox Code Playgroud)

此代码片段迭代设置了控制终端并与该进程的终端匹配的所有进程(实际上是它们的 ID)的列表。它检查每个进程的环境中的DISPLAY变量,并在找到变量后立即满足。找到DISPLAY变量后,它会停止迭代列表并echo获取结果。

这将打印运行脚本的活动显示。