web-dev-qa-db-fra.com

Ouvrir une fenêtre sur un écran X distant (pourquoi "Impossible d'ouvrir l'écran")?

Il était une fois,

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

après ssh dans mon bureau depuis mon ordinateur portable, le totem jouerait movie.avi sur mon bureau.

Maintenant, cela donne l'erreur:

No protocol specified
Cannot open display:

J'ai réinstallé Debian Squeeze quand il est devenu stable sur les deux ordinateurs, et je suppose que j'ai cassé la configuration.

J'ai googlé à ce sujet, et je ne peux pas pour la vie de moi comprendre ce que je suis censé faire.

(VLC a une interface HTTP qui fonctionne, mais ce n'est pas aussi pratique que ssh.)

Le même problème se pose lorsque j'essaie d'exécuter cela à partir d'un travail cron.

83
justin cress

(Adapté de Linux: wmctrl ne peut pas ouvrir l'affichage lorsque la session est lancée via ssh + screen )

AFFICHAGE et AUTORITÉ

Un programme X a besoin de deux informations pour se connecter à un écran X.

  • Il a besoin de l'adresse de l'écran, qui est généralement :0 Lorsque vous êtes connecté localement ou :10, :11, Etc. lorsque vous êtes connecté à distance (mais le nombre peut changer en fonction du nombre de connexions X actives). L'adresse de l'affichage est normalement indiquée dans la variable d'environnement DISPLAY.

  • Il a besoin du mot de passe pour l'affichage. Les mots de passe d'affichage X sont appelés cookies magiques . Les cookies magiques ne sont pas spécifiés directement: ils sont toujours stockés dans des fichiers d'autorité X, qui sont une collection d'enregistrements de la forme "afficher :42 Contient un cookie 123456". Le fichier d'autorité X est normalement indiqué dans la variable d'environnement XAUTHORITY. Si $XAUTHORITY N'est pas défini, les programmes utilisent ~/.Xauthority.

Vous essayez d'agir sur les fenêtres affichées sur votre bureau. Si vous êtes la seule personne à utiliser votre ordinateur de bureau, il est très probable que le nom d'affichage soit :0. Trouver l'emplacement du fichier d'autorité X est plus difficile, car avec gdm tel que configuré sous Debian Squeeze ou Ubuntu 10.04, il se trouve dans un fichier avec un nom généré aléatoirement. (Vous n'avez eu aucun problème auparavant car les versions antérieures de gdm utilisaient le paramètre par défaut, c'est-à-dire les cookies stockés dans ~/.Xauthority.)

Obtention des valeurs des variables

Voici quelques façons d'obtenir les valeurs de DISPLAY et XAUTHORITY:

  • Vous pouvez systématiquement démarrer une session d'écran à partir de votre bureau, peut-être automatiquement dans vos scripts de connexion (à partir de ~/.profile; Mais ne le faites que si vous vous connectez sous X: testez si DISPLAY est défini sur une valeur commençant avec : (qui devrait couvrir tous les cas que vous êtes susceptible de rencontrer)). Dans ~/.profile:

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

    Ensuite, dans la session ssh:

    screen -d -r local
    
  • Vous pouvez également enregistrer les valeurs de DISPLAY et XAUTHORITY dans un fichier et rappeler les valeurs. Dans ~/.profile:

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

    Dans la session ssh:

    . ~/.local-display-setup.sh
    screen
    
  • Vous pouvez détecter les valeurs de DISPLAY et XAUTHORITY à partir d'un processus en cours d'exécution. C'est plus difficile à automatiser. Vous devez déterminer le PID d'un processus connecté à l'écran sur lequel vous souhaitez travailler, puis obtenir les variables d'environnement à partir de /proc/$pid/environ (eval export $(</proc/$pid/environ tr \\0 \\n | grep -E '^(DISPLAY|XAUTHORITY)=') ¹).

Copie des cookies

Une autre approche (suivant une suggestion de Arrowmaster ) consiste à ne pas essayer d'obtenir la valeur de $XAUTHORITY Dans la session ssh, mais à la place de faire en sorte que la session X copie ses cookies dans ~/.Xauthority. Étant donné que les cookies sont générés à chaque connexion, ce n'est pas un problème si vous conservez des valeurs périmées dans ~/.Xauthority.

Il peut y avoir un problème de sécurité si votre répertoire personnel est accessible via NFS ou un autre système de fichiers réseau qui permet aux administrateurs distants d'afficher son contenu. Ils auraient toujours besoin de se connecter à votre machine d'une manière ou d'une autre, à moins que vous n'ayez activé X TCP (Debian les a désactivées par défaut). Donc pour la plupart des gens, cela non plus ne s'applique pas (non NFS) ou n'est pas un problème (pas de connexions X TCP).

Pour copier les cookies lorsque vous vous connectez à votre session de bureau X, ajoutez les lignes suivantes à ~/.xprofile Ou ~/.profile (Ou à un autre script qui est lu lorsque vous vous connectez):

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

¹ En principe, cela manque de guillemets appropriés, mais dans ce cas précis, $DISPLAY Et $XAUTHORITY Ne contiendront aucun métacaractère Shell.

J'ai résolu ce problème en ajoutant

xhost +si:localuser:$USER

à ~/.xprofile. Je ne sais pas si cela est tout à fait sécurisé (je serais très intéressé d'entendre ce que les gens plus avertis pensent), mais je suppose que c'est beaucoup mieux que de désactiver le contrôle d'accès (avec xhost +), comme cela est généralement suggéré lorsque vous recherchez ce problème sur Google.

20
edam

Tu dois export DISPLAY=:0.0

7
asoundmove

Fonctionne pour moi, debian wheezy -> ubuntu fidèle.

Remarque: dans ce cas, le serveur n'exécute pas de gestionnaire d'affichage, c'est une machine virtuelle "sans tête" sans carte graphique ni moniteur connecté.

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

L'affichage X sur ordinateur portable montre la sortie de xterm exécutée sur le serveur.

Déboguer en utilisant:

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 va déverser des tas de détails sanglants sur ce qu'il fait, vous devriez être en mesure de deviner où il est bloqué - en attendant une connexion ou autre chose.

En une seule ligne ..

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