Como testar programaticamente se é possível conectar-se ao servidor X especificado em $ DISPLAY

8

Este é um meio termo entre a programação e o administrador do servidor, mas este parece ser o local mais relevante para isso.

Estou procurando uma maneira de determinar se a variável ' $DISPLAY' está anunciando um XServer com o qual podemos realmente nos conectar, ou seja, se toda a autenticação e outros enfeites existem para permitir que outras coisas sejam executadas.

Idealmente, estou procurando por alguma ferramenta shell-end que retorne verdadeiro / falso, que pode ser usada em um script de construção para determinar se os outros testes nele (que eu não controlo) devem ser executados ou não.

No momento, os testes simplesmente verificam a envvariável " $DISPLAY" e, se houver, tentam se conectar e, quando a conexão não funciona, os testes assumem a falha do teste, não apenas a tela não é conectável.

Eu só preciso ser capaz de fazer

if [[ ! can_connect_to_X ]] ; then 
    unset DISPLAY
fi

Para interromper esses testes com problemas mentais graves.

Em uma situação ideal, a ferramenta necessária para fazer isso deve ser fornecida com as próprias bibliotecas do X Client, para não incorrer em dependências especiais e poder assumir que, se o utilitário não estiver lá, não podemos conectar a nenhum monitor.

Kent Fredric
fonte

Respostas:

6

Você pode tentar com o comando xset:

if [[ ! $(xset -q) ]]; then
   # the X server is not reachable
else
   # the X server is reachable
fi
slubman
fonte
Embora eu tenha acabado de usá-lo de uma maneira mais complexa, o xset parece estar mais provavelmente instalado que o xdpyinfo.
22710 Kent Kentric
2

Eu estou supondo que há uma solução melhor. Mas você sempre pode usar uma ferramenta pequena como o xclock e verificar o status da saída.

if [[ ! xclock ]]; then
  exit 1
fi
pkill xclock

Mas cara, isso é feio :-)

Menos Hacky, coloque o seguinte em checkX.c:

#include <X11/Xlib.h>
#include <stdio.h>

int main() 
{
    Display *display;
    if( ! (display=XOpenDisplay(NULL) ) ) {
        return(1);
    }
    return 0;
}

Então:

gcc -lX11 checkX.c -o checkX
chmod +x checkX

Por último:

if ./checkX; then
   echo "We are good to go!"
fi
Kyle Brandt
fonte
Sim, essa é a primeira coisa que considerei, mas queria algo que não criava visualmente uma janela: /. Eu até pensei em fazer xclock e depois matá-lo.
23710 Kent Kentric
xclock -geometry 1x1 é sobre o melhor que eu posso fazer para eliminar a intrusão visual: /, mas também aloca uma tarefa espaço na barra de tarefas :(
Kent Fredric
Esse é o primeiro programa X que eu já escrito em C, por isso, não tenho certeza se ele é totalmente confiável :-)
Kyle Brandt
E não a coisa portátil mais ;-)
Kyle Brandt
Isso é incrivelmente útil, infelizmente, minhas restrições são um pouco mais rígidas. Verdade seja dita, estou escrevendo um ebuild (gentoo), então tenho que fazer praticamente / tudo / com shell e assumir que os aplicativos estarão lá antes, e não posso adicionar blobs binários antes dos aplicativos de terceiros :)
Kent Fredric
1

Heres um WayToDoIt possível, não tenho certeza de como é bom.

  x_works(){
     # If there is no xdpyinfo
     # Bash will return 127
     # If X cant connect, it returns 1
     # If X can connect, it returns 0
     xdpyinfo 1>/dev/null 2>&1
     WORKS="$?"
     return $WORKS
  }

  if x_works; then 
   ...

Isso parece estar funcionando.

Kent Fredric
fonte
Na minha máquina Fedora 11, estou recebendo: $ xdpyinfo 1 use: xdpyinfo [opções] De qualquer forma, acho que parece uma boa ideia usar o programa xdpyinfo.
Cristian Ciupitu 26/08/09
o '1' não existe redirecionamento stderr para o bash;), e não um xdpyinfo param :)
Kent Fredric