Abra uma janela em um display X remoto (por que “Cannot open display”)?

75

Era uma vez,

DISPLAY=:0.0 totem /path/to/movie.avi

depois de fazer ssh no meu desktop do meu laptop, faria com que o totem tocasse movie.avi na minha área de trabalho.

Agora, é exibido o erro:

No protocol specified
Cannot open display:

Eu reinstalei o Debian squeeze quando ele ficou estável em ambos os computadores, e eu acho que quebrei a configuração.

Eu pesquisei sobre isso, e não posso para a vida de mim descobrir o que eu deveria estar fazendo.

(o VLC tem uma interface HTTP que funciona, mas não é tão conveniente quanto o ssh.)

O mesmo problema surge quando tento executar isso a partir de um trabalho cron.

    
por justin cress 25.03.2011 / 22:24

4 respostas

73

(adaptado de Linux: o wmctrl não pode abrir a tela quando a sessão é iniciada via tela ssh + )

DISPLAY e AUTORIDADE

Um programa X precisa de duas informações para se conectar a um monitor X.

  • Ele precisa do endereço da exibição, que normalmente é :0 quando você está conectado localmente ou :10 , :11 , etc. quando você está conectado remotamente (mas o número pode mudar dependendo de quantas conexões X estão ativas). O endereço da exibição é normalmente indicado na variável de ambiente DISPLAY .

  • Precisa da senha para a exibição. X senhas de exibição são chamadas de cookies mágicos . Cookies mágicos não são especificados diretamente: eles são sempre armazenados em arquivos de autoridade X, que são uma coleção de registros do formulário “display :42 has cookie 123456 ”. O arquivo de autoridade X é normalmente indicado na variável de ambiente XAUTHORITY . Se $XAUTHORITY não estiver definido, os programas usarão ~/.Xauthority .

Você está tentando agir nas janelas exibidas em sua área de trabalho. Se você for a única pessoa que usa sua máquina de desktop, é muito provável que o nome de exibição seja :0 . Encontrar a localização do arquivo de autoridade X é mais difícil, porque com o gdm como configurado no Debian squeeze ou no Ubuntu 10.04, ele está em um arquivo com um nome gerado aleatoriamente. (Você não teve nenhum problema antes porque as versões anteriores do gdm usavam a configuração padrão, ou seja, cookies armazenados em ~/.Xauthority .)

Obtendo os valores das variáveis

Aqui estão algumas maneiras de obter os valores de DISPLAY e XAUTHORITY :

  • Você pode iniciar sistematicamente uma sessão de tela a partir da sua área de trabalho, talvez automaticamente em seus login scripts (de ~/.profile ; mas faça isso somente se efetuar login em X: teste se DISPLAY estiver definido como um valor começando com : (que deve cobrir todos os casos que você provavelmente encontrará). Em ~/.profile :

    case $DISPLAY in
      :*) screen -S local -d -m;;
    esac
    

    Então, na sessão ssh:

    screen -d -r local
    
  • Você também pode salvar os valores de DISPLAY e XAUTHORITY em um arquivo e recuperar os valores. Em ~/.profile :

    case $DISPLAY in
      :*) export | grep -E '(^| )(DISPLAY|XAUTHORITY)=' >~/.local-display-setup.sh;;
    esac
    

    Na sessão ssh:

    . ~/.local-display-setup.sh
    screen
    
  • Você pode detectar os valores de DISPLAY e XAUTHORITY de um processo em execução. Isso é mais difícil de automatizar. Você precisa descobrir o PID de um processo conectado à exibição na qual deseja trabalhar e, em seguida, obter as variáveis de ambiente em /proc/$pid/environ ( eval export $(</proc/$pid/environ tr \0 \n | grep -E '^(DISPLAY|XAUTHORITY)=') ¹).

Copiando os cookies

Outra abordagem (seguindo uma sugestão de Arrowmaster ) é não tentar obter o valor de $XAUTHORITY na sessão ssh, mas em vez disso, faça a sessão X copiar seus cookies em ~/.Xauthority . Como os cookies são gerados sempre que você efetua login, não é um problema manter os valores obsoletos em ~/.Xauthority .

Pode haver um problema de segurança se o seu diretório pessoal estiver acessível via NFS ou outro sistema de arquivos de rede que permita que administradores remotos visualizem seu conteúdo. Eles ainda precisam se conectar à sua máquina de alguma forma, a menos que você tenha habilitado as conexões X TCP (o Debian as descarta por padrão). Portanto, para a maioria das pessoas, isso não se aplica (sem NFS) ou não é um problema (não há conexões X-TCP).

Para copiar cookies quando você fizer login na sua sessão X de área de trabalho, adicione as seguintes linhas a ~/.xprofile ou ~/.profile (ou algum outro script que seja lido quando você efetuar login):

case $DISPLAY:$XAUTHORITY in
  :*:?*)
    # DISPLAY is set and points to a local display, and XAUTHORITY is
    # set, so merge the contents of '$XAUTHORITY' into ~/.Xauthority.
    XAUTHORITY=~/.Xauthority xauth merge "$XAUTHORITY";;
esac

¹ Em princípio, isso não possui as devidas citações, mas nesta instância específica, $DISPLAY e $XAUTHORITY não conterão nenhum metacaractere de casca.

    
por 25.03.2011 / 23:39
18

Eu resolvi esse problema adicionando

xhost +si:localuser:$USER

para ~/.xprofile . Eu não sei se isso é totalmente seguro (eu estaria muito interessado em ouvir o que pessoas mais bem informadas pensam), mas eu estou supondo que é muito melhor do que desligar o controle de acesso (com xhost + ) como é comumente sugerido quando você pesquisar no Google por esse problema.

    
por 04.12.2011 / 22:59
8

Você precisa export DISPLAY=:0.0

    
por 25.03.2011 / 23:28
3

Funciona para mim, debian wheezy - > Ubuntu confiável.

Nota: neste caso, o servidor não está executando um gerenciador de exibição, é uma máquina virtual 'sem cabeçalho' sem placa gráfica ou monitor conectado.

bob@laptop:~$ grep -iB 1 tcp /etc/gdm3/daemon.conf
[security]
DisallowTCP = false
bob@laptop:~$ ssh -C -R 6000:127.0.0.1:6000 alice@server
X11 forwarding request failed on channel 0
alice@server:~$ export DISPLAY=:0.0
alice@server:~$ xterm

A exibição X no laptop mostra a saída do xterm em execução no servidor.

Depurar usando:

bob@laptop:~/tmp$ nc -v 127.0.0.1 6001
localhost [127.0.0.1] 6001 (x11-1) : Connection refused
bob@laptop:~/tmp$ nc -v 127.0.0.1 6000
localhost [127.0.0.1] 6000 (x11) open
alice@server:~$ nc -v 127.0.0.1 6000
Connection to 127.0.0.1 6000 port [tcp/x11] succeeded!*
alice@server:~$ strace xterm

strace derramará muitos detalhes sobre o que está fazendo, você deve ser capaz de adivinhar onde fica preso - esperando por uma conexão ou algo assim.

Em uma linha ...

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"
    
por 01.05.2015 / 01:22

Tags