Abrir uma janela em um monitor X remoto (por que "Não é possível abrir o monitor")?

81

Era uma vez,

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

depois de ssh na minha área de trabalho do meu laptop faria com que o totem fosse reproduzido movie.avina minha área de trabalho.

Agora dá o erro:

No protocol specified
Cannot open display:

Reinstalei o Debian squeeze quando ele ficou estável nos dois computadores e acho que quebrei a configuração.

Eu pesquisei sobre isso e não consigo descobrir o que devo 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 em um trabalho cron.

justin cress
fonte
1
Sua máquina remota mostra um arquivo .Xauthority? A outra pergunta óbvia é: seu servidor e cliente ssh estão configurados para permitir o encaminhamento do X? Qual comando você usou para ssh?
Faheem Mitha 25/03
1
estou tentando encaminhar o X? Quero que o comando seja executado no host, não no cliente. Meu comando ssh é apenas ssh me @ host find. A autoridade no computador host não corresponde a nenhum arquivo.
justin agrião
Como Faheem sugere, há uma boa mudança de que seu problema se deve ao totemnão encontrar seu cookie X, e você precisa definir XAUTHORITYo valor adequado, ou seja, o valor da sua sessão regular na área de trabalho. Leia Linux: wmctrl não pode abrir a tela quando a sessão é iniciada via tela ssh + para obter algum plano de fundo; veja também a resposta relacionada Como root, posso iniciar um programa gráfico na área de trabalho de outro usuário? .
Gilles
1
tudo bem, fisicamente sentado no computador e digitando echo $ XAUTHORITY fornece / var / run / gdm3 / auth-for-jcress-bb32gX / banco de dados na sessão ssh, digitando echo $ DISPLAY = (o caminho acima) não resolve o problema
justin cress
1
Eu culpo gdm3, por que não poderiam ter apenas mantido $XAUTHORITYem ~/.Xauthoritycomo todo mundo espera que ele seja.
Arrowmaster

Respostas:

78

(Adaptado do Linux: o wmctrl não pode abrir a exibição 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 exposição, que é normalmente :0quando você está logado localmente ou :10, :11etc. quando você está logado remotamente (mas o número pode mudar dependendo de quantos X conexões estão ativos). O endereço da tela é normalmente indicado na DISPLAYvariável de ambiente.

  • Ele precisa da senha para a exibição. As senhas de exibição X são chamadas de cookies mágicos . Os 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 no formato “display :42has cookie 123456”. O arquivo de autoridade X é normalmente indicado na XAUTHORITYvariável de ambiente. Se $XAUTHORITYnão estiver definido, os programas serão usados ~/.Xauthority.

Você está tentando agir nas janelas exibidas na área de trabalho. Se você é a única pessoa que usa sua máquina de mesa, é 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 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, os cookies armazenados ~/.Xauthority.)

Obtendo os valores das variáveis

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

  • Você pode iniciar sistematicamente uma sessão de tela na área de trabalho, talvez automaticamente em seus scripts de logon (a partir de ~/.profile; mas fazê-lo apenas se estiver efetuando login no X: test se DISPLAYestiver definido com um valor começando com :(que deve cobrir todos os casos em 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 DISPLAYe XAUTHORITYem 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 DISPLAYe XAUTHORITYde um processo em execução. Isso é mais difícil de automatizar. Você precisa descobrir o PID de um processo conectado ao monitor em que deseja trabalhar e, em seguida, obter as variáveis ​​de ambiente de /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 $XAUTHORITYna sessão ssh, mas fazer com que a sessão X copie seus cookies ~/.Xauthority. Como os cookies são gerados sempre que você faz login, não é um problema se você mantiver valores obsoletos ~/.Xauthority.

Pode haver um problema de segurança se o diretório inicial estiver acessível por 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 ativado as conexões X TCP (o Debian as desativou por padrão). Portanto, para a maioria das pessoas, isso não se aplica (sem NFS) ou não é um problema (sem conexões X TCP).

Para copiar cookies ao fazer login na sessão X da área de trabalho, adicione as seguintes linhas a ~/.xprofileou ~/.profile(ou algum outro script que é lido quando você faz 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

Principle Em princípio, falta uma citação adequada, mas neste caso específico $DISPLAYe $XAUTHORITYnão contém nenhum metacaractere do shell.

Gilles
fonte
2
Uma maneira de automatizar isso seria criar um ~/.xprofileque só deve ser executado durante o login do X e fazer com que ele crie / atualize ~/.Xauthoritycom as informações corretas. Um link simbólico seria suficiente?
Arrowmaster
@ Arrowmaster: Essa é uma boa sugestão. Eu não tinha pensado nisso. Não funcionará em todos os casos, por exemplo, se você fizer login em mais de uma sessão X (em terminais diferentes, com vnc,…), mas é simples e é bom o suficiente para o uso típico. Um link simbólico é o melhor caminho. Hmm, na verdade, há uma maneira melhor e simples: você pode copiar as informações ~/.Xauthority.
Gilles
1
Iria colocar algo como xauth extract - $DISPLAY | xauth -f "$HOME/.Xauthority" merge -em ~/.xprofileresolver o caso de múltiplos $ DISPLAY de?
Arrowmaster
@Arrowmaster: Que problema você vê com vários monitores? Embora seu código possa ser um pouco mais limpo, em princípio, uma vez que você está apenas extraindo informações sobre a tela em que está interessado, não vejo nada de errado com uma simples mesclagem no caso do solicitante ou mesmo fora de circunstâncias muito incomuns.
Gilles
1
Ler o ambiente a partir de um processo existente conectado à tela é inesperado e deliciosamente mau. Eu aprovo de todo o coração. O Unix.SE precisa de um selo Evil Genius ™ para isso.
Derobert
19

Eu resolvi esse problema adicionando

xhost +si:localuser:$USER

para ~/.xprofile. Não sei se isso é totalmente seguro (eu ficaria muito interessado em ouvir o que as pessoas mais instruídas pensam), mas acho que é muito melhor do que desativar o controle de acesso (com xhost +), como é comumente sugerido quando você google para este problema.

edam
fonte
1
localuserendereços interpretados pelo servidor são completamente seguros. O Debian ainda faz isso por padrão como parte do processo de login (in /etc/X11/Xsession.d/35x11-common_xhost-local). Consulte a página do manual Xsecurity para obter mais detalhes.
Sam Morris
Se você estiver em uma LAN, xhost +é provavelmente o suficiente na maioria dos casos ...
Alexis Wilke
Você seria capaz de explicar o que esse comando significa?
alpha_989
@ alpha_989: significa "Conceder acesso [+] a qualquer aplicativo [localuser] em execução local que esteja sendo executado como eu [$ USER]." O "si" é apenas cola (consulte xhost(1)e Xsecurity(7)para documentos). Por si só, esse comando não permite nenhum tipo de acesso remoto ou encaminhamento X11 (para o qual o mecanismo "cookie mágico" é geralmente preferido xhost).
Kevin
7

Você precisa export DISPLAY=:0.0

asoundmove
fonte
Não. O Unix não requer uma exportação quando a variável é gravada na mesma linha. Essa variável é efetiva até que a linha termine.
Alexis Wilke
Na verdade, você está certo.
Asoundmove 18/05
Esta resposta está claramente errada e deve ser excluída.
Piotr Dobrogost
Não sabia que apenas digitar DISPLAY =: 0.0 definiria o nome da variável. Obrigado @asoundmove. No entanto, acho que: 0.0 é o valor da variável DISPLAY na tela do servidor. Se você estiver efetuando login no Putty, a variável DISPLAY deverá 10 ou superior. então deve ser DISPLAY =: 10
alpha_989 7/07
3

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

Nota: nesse caso, o servidor não está executando um gerenciador de exibição, é uma máquina virtual 'sem cabeça' 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 tela X no laptop mostra a saída do xterm em execução no servidor.

Depure 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 Se você der um monte de detalhes sangrentos sobre o que está fazendo, você será capaz de adivinhar onde fica parado - esperando por uma conexão ou o que quer que seja.

Em uma linha ..

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"
jmullee
fonte