Como descobrir o número atual (ativo) do XServer DISPLAY?

3

Estou usando o Arch Linux e as coisas não são tão fáceis quando você tenta descobrir o atual Xorg DISPLAY (não através da variável env).

Aqui está um exemplo de trabalho:

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

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

Isso funciona em alguns casos, em outros não:

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

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

Causa:

$ 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

O usuário convidado (tty3) teve sua sessão lançada usando pts (pseudo terminal).

Estou usando o gdm e ele inicia servidores xorg sem um comando específico (sem esclarecer o número de exibição).

$ 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

Então, o milhão de perguntas é: Como descobrir o atual (em uso) XServer DISPLAY número? Atual porque, como acima, podemos ter múltiplos servidores (múltiplos usuários).

    
por Geyslan G. Bem 16.05.2015 / 22:39

4 respostas

5

Você pode tentar usar loginctl list-sessions para obter a lista de sessões e, em seguida, usar loginctl show-session -p Display -p Active <session ID> em cada uma delas para obter o número de exibição do X11 associado à sessão ativa no momento.

Algo parecido com isto (no 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)

Aqui, o $TARGET_DISPLAY é uma matriz, porque, hipoteticamente, pode haver mais de uma sessão ativa (em um sistema com várias sedes). Se isso não for possível em sua configuração, você poderá torná-la uma variável simples e adicionar uma instrução break 2 após a atribuição para sair de ambos os loops.

NO ENTANTO ...

... isso não funciona mais com o GDM, porque neste caso o servidor X é iniciado dentro da sessão (com privilégios de usuário) e /usr/bin/gdm-x-session não comunica essas informações de volta a logind (devido à falta de uma API para isso).

Em outros casos (quando o servidor X é iniciado pelo DM antes da criação da sessão), isso provavelmente funcionará. Não tenho conhecimento de nenhum outro método, desculpe.

    
por 20.05.2015 / 09:00
4

Bem, como atual eu quero dizer active Exibição de um servidor XOrg. Lembre-se que podemos ter mais de um servidor XOrg rodando e eles podem ser multi-head, o que dificulta a manipulação das coisas.

A outra nota importante é que a variável DISPLAY em alguns casos não pode ser acessada (por exemplo, systemd).

Após algumas discussões em commandlinefu , obtive este resultado:

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

Este trecho itera sobre uma lista de todos os processos (na verdade, seus IDs), onde o terminal de controle é definido e corresponde ao terminal deste processo. Ele verifica o ambiente de cada processo para a variável DISPLAY e fica satisfeito assim que encontrar um. Tendo encontrado uma variável DISPLAY , ela pára de iterar a lista e echo s o resultado.

Isso imprimirá a exibição ativa que executa o script.

    
por 29.01.2017 / 14:14
2

O próximo script lista o nome de usuário e o número de exibição dos usuários conectados quando o terminal correspondente está ativo.

w -hs | \
awk -v tty="$(cat /sys/class/tty/tty0/active)" \
    '$2 == tty && $3 != "-" {print $1 FS $3}'

Resultado:

myuser: 0

    
por 29.01.2017 / 10:40
0

Esta é a minha solução baseada em outras respostas:

#!/bin/bash

DISPLAY=""

# Guess the active DISPLAY
while read in session; do
    # Explode to needed variables
    set -- $session; tty=$1; display=$2
    # 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"

Isso verifica todas as sessões de login que possuem sessões X também. Se o tty também for compatível, podemos ter certeza de que é a sessão X ativa, senão usamos o 1º.

Esse script também pode ser estendido para corresponder ao usuário atual, se você quiser.

    
por 10.01.2018 / 11:15