然而...

然而...

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

这是一个工作示例:

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

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

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

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

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

原因:

$ 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

来宾用户(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

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

答案1

您可以尝试使用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)

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

然而...

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

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

答案2

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

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

经过一番讨论后命令行fu,我得到这个结果:

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

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

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

答案3

这是在同一主机上运行两个服务器的示例。我曾经startx启动过它们,正如您从pstree -pl下面的输出中看到的那样。第一个带有 set 的子进程$DISPLAY.xinitrc

|-login(698)---zsh(1077)---startx(1359)---xinit(1381)-+-.xinitrc(1386)...

这是命令;如果您有不同的设置,可以.xinitrc在此处更改为其他设置:

$ pgrep .xinitrc | while read i; do \
    d=$(cat /proc/$i/environ | tr '\0' '\n' | grep DISPLAY); \
    echo -n $d" "; eval $d xprintidle; \
  done | sort -n -k 2
DISPLAY=:1 93
DISPLAY=:0 603301

这些数字显示每个显示器的空闲时间(以毫秒为单位)。最上面一行显示最近活动(最少空闲)的显示屏。

就其价值而言,其他答案都不适合我。

答案4

这是我基于其他答案的解决方案:

#!/bin/bash

DISPLAY=""

# Guess the active DISPLAY
while read session; do
    # Explode to needed variables
    set -- $session; tty=$2; display=$3
    # If there is an X session in thet TTY
    if [ "$display" != "-" ]; then
        # 1st non root display is used if TTY is not matched with the active
        [ "$DISPLAY" == "" ] && DISPLAY="$display"
        # If it is the active TTY we can stop, this is the active X!
        [ "$tty" == "$(cat /sys/class/tty/tty0/active)" ] && DISPLAY="$display";
    fi
done <<< "$(w -hs)"

echo "$DISPLAY"

这会检查所有具有 X 会话的登录会话。如果 tty 也匹配,我们可以确定它是活动的 X 会话,否则我们使用第一个。

如果需要,也可以扩展此脚本以匹配当前用户。

相关内容