Otwórz okno na zdalnym wyświetlaczu X (dlaczego „Nie można otworzyć wyświetlacza”)?


81

Pewnego razu,

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

po ssh'owaniu na moim pulpicie z laptopa spowodowałoby, że totem grał movie.avina moim pulpicie.

Teraz wyświetla błąd:

No protocol specified
Cannot open display:

Ponownie zainstalowałem wyciskanie Debiana, gdy stało się stabilne na obu komputerach i chyba zepsułem konfigurację.

Przejrzałem to i nie mogę przez całe życie rozgryźć, co powinienem robić.

(VLC ma interfejs HTTP, który działa, ale nie jest tak wygodny jak ssh.)

Ten sam problem pojawia się, gdy próbuję uruchomić to z zadania crona.


1
Czy twój zdalny komputer wyświetla plik .Xauthority? Drugim oczywistym pytaniem jest - czy twój serwer i klient ssh jest skonfigurowany tak, aby umożliwić przekazywanie X? Jakiego polecenia użyłeś do ssh?
Faheem Mitha

1
próbuję przesłać X? Chcę, aby polecenie zostało wykonane na hoście, a nie na kliencie. Moje polecenie ssh to po prostu ssh me @ host locate. Autorytet na komputerze hosta nie pasuje do żadnych plików.
justin cress

Jak sugeruje Faheem, dobra zmiana polega na tym, że twój problem wynika z totembraku pliku cookie X i musisz ustawić XAUTHORITYodpowiednią wartość, tj. Wartość w zwykłej sesji na pulpicie. Czytaj Linux: wmctrl nie może otworzyć ekranu, gdy sesja jest inicjowana przez ssh + screen dla jakiegoś tła; zobacz także pokrewną odpowiedź. Jako root mogę uruchomić program graficzny na pulpicie innego użytkownika? .
Gilles,

1
w porządku, fizycznie siedząc przy komputerze i wpisując echo $ XAUTHORITY daje / var / run / gdm3 / auth-for-jcress-bb32gX / database w sesji ssh, wpisanie echa $ DISPLAY = (ścieżka powyżej) nie rozwiązuje problemu
justin cress

1
Obwiniam GDM3, dlaczego nie mogli po prostu utrzymać $XAUTHORITYsię ~/.Xauthoritytak, jak wszyscy się spodziewają.
Arrowmaster

Odpowiedzi:


78

( Zaadaptowano z systemu Linux: wmctrl nie może otworzyć ekranu, gdy sesja jest inicjowana przez ssh + screen )

WYŚWIETLANIE I ORGAN

Program X potrzebuje dwóch informacji, aby połączyć się z wyświetlaczem X.

  • Potrzebuje adresu wyświetlacza, który zazwyczaj :0jest zalogowany lokalnie lub :10, :11itp., Gdy logujesz się zdalnie (ale liczba może się zmienić w zależności od liczby aktywnych połączeń X). Adres wyświetlacza jest zwykle wskazywany w DISPLAYzmiennej środowiskowej.

  • Potrzebuje hasła do wyświetlacza. Hasła wyświetlania X nazywane są magicznymi ciasteczkami . Magiczne pliki cookie nie są określane bezpośrednio: zawsze są przechowywane w plikach autoryzacji X, które są zbiorem zapisów w formie „display :42ma ciasteczko 123456”. Plik uprawnień X jest zwykle wskazywany w XAUTHORITYzmiennej środowiskowej. Jeśli $XAUTHORITYnie jest ustawiony, programy używają ~/.Xauthority.

Próbujesz działać w oknach wyświetlanych na pulpicie. Jeśli jesteś jedyną osobą korzystającą z komputera, najprawdopodobniej jest to nazwa wyświetlana :0. Znalezienie lokalizacji pliku autorytetu X jest trudniejsze, ponieważ z gdm skonfigurowanym w Debian squeeze lub Ubuntu 10.04, znajduje się w pliku o losowo generowanej nazwie. (Wcześniej nie miałeś problemu, ponieważ wcześniejsze wersje gdm korzystały z ustawienia domyślnego, tj. Zapisanych plików cookie ~/.Xauthority.)

Uzyskiwanie wartości zmiennych

Oto kilka sposobów uzyskania wartości DISPLAYi XAUTHORITY:

  • Możesz systematycznie uruchamiać sesję ekranową z pulpitu, być może automatycznie w skryptach logowania (z ~/.profile; ale rób to tylko wtedy, gdy logujesz się w X: test, jeśli DISPLAYjest ustawiona na wartość zaczynającą się od :(która powinna obejmować wszystkie przypadki, w których prawdopodobnie spotkać)). W ~/.profile:

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

    Następnie w sesji ssh:

    screen -d -r local
    
  • Można również zapisać wartości DISPLAYi XAUTHORITYw pliku i przywołać wartości. W ~/.profile:

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

    W sesji ssh:

    . ~/.local-display-setup.sh
    screen
    
  • Można wykryć wartości DISPLAYi XAUTHORITYod uruchomionego procesu. To jest trudniejsze do zautomatyzowania. Musisz ustalić PID procesu podłączonego do wyświetlacza, nad którym chcesz pracować, a następnie pobrać zmienne środowiskowe z /proc/$pid/environ( eval export $(</proc/$pid/environ tr \\0 \\n | grep -E '^(DISPLAY|XAUTHORITY)=')¹).

Kopiowanie ciasteczek

Inne podejście (zgodnie z sugestią Arrowmaster ) polega na tym, aby nie próbować uzyskać wartości $XAUTHORITYw sesji ssh, ale zamiast tego zmusić sesję X do skopiowania plików cookie ~/.Xauthority. Ponieważ pliki cookie są generowane przy każdym logowaniu, nie ma problemu, jeśli utrzymasz nieaktualne wartości ~/.Xauthority.

Problem z bezpieczeństwem może wystąpić, jeśli katalog domowy jest dostępny za pośrednictwem NFS lub innego sieciowego systemu plików, który umożliwia zdalnym administratorom przeglądanie jego zawartości. Nadal będą musieli jakoś połączyć się z twoim komputerem, chyba że włączysz połączenia X TCP (domyślnie Debian je wyłącza). Tak więc dla większości osób nie dotyczy to (brak NFS) lub nie stanowi problemu (brak połączeń X TCP).

Aby skopiować pliki cookie podczas logowania do sesji pulpitu X, dodaj następujące wiersze do ~/.xprofilelub ~/.profile(lub innego skryptu czytanego podczas logowania):

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

¹ Zasadniczo brakuje odpowiedniego cytowania, ale w tym konkretnym przypadku $DISPLAYi $XAUTHORITYnie będzie zawierał żadnego metaznaku powłoki.


2
Jednym ze sposobów na zautomatyzowanie tego byłoby utworzenie takiego, ~/.xprofilektóry powinien być uruchamiany tylko podczas logowania X i zlecenie utworzenia / aktualizacji ~/.Xauthorityz poprawnymi informacjami. Czy wystarczy dowiązanie symboliczne?
Arrowmaster

@Arrowmaster: To dobra sugestia. Nie myślałem o tym. Nie będzie działać we wszystkich przypadkach, na przykład, jeśli zalogujesz się do więcej niż jednej sesji X (na różnych terminalach, z vnc,…), ale jest prosty i wystarczający do typowego użycia. Łącze symboliczne to najlepszy sposób. Hmm, właściwie jest lepszy, prosty sposób: możesz skopiować informacje ~/.Xauthority.
Gilles,

1
Czy umieszczenie czegoś takiego xauth extract - $DISPLAY | xauth -f "$HOME/.Xauthority" merge -w ~/.xprofilerozwiązaniu przypadku wielu $ DISPLAY?
Arrowmaster

@Arrowmaster: Jaki problem występuje z wieloma wyświetlaczami? Chociaż twój kod może być nieco bardziej przejrzysty, ponieważ wyodrębniasz tylko informacje o ekranie, który Cię interesuje, nie widzę nic złego w prostym scaleniu w przypadku pytającego lub w naprawdę wyjątkowych okolicznościach.
Gilles,

1
Odczytywanie otoczenia z istniejącego procesu podłączonego do wyświetlacza jest nieoczekiwane, ponieważ jest cudownie złe. Akceptuję z całego serca. Unix.SE potrzebuje do tego plakietki Evil Genius ™.
derobert

19

Rozwiązałem ten problem, dodając

xhost +si:localuser:$USER

do ~/.xprofile. Nie wiem, czy jest to całkowicie bezpieczne (byłbym bardzo zainteresowany, aby dowiedzieć się, co myślą bardziej znający się na rzeczy ludzie), ale zgaduję, że jest to o wiele lepsze niż wyłączenie kontroli dostępu (z xhost +), jak to zwykle sugeruje się, gdy ty google dla tego problemu.


1
localuseradresy interpretowane przez serwer są całkowicie bezpieczne. Debian robi to domyślnie nawet w ramach procesu logowania (in /etc/X11/Xsession.d/35x11-common_xhost-local). Więcej informacji znajduje się na stronie podręcznika Xsecurity .
Sam Morris

Jeśli jesteś w sieci LAN, xhost +prawdopodobnie w większości przypadków wystarczy ...
Alexis Wilke

Czy byłbyś w stanie wyjaśnić, co oznacza to polecenie?
alpha_989,

@ alpha_989: Oznacza „Przyznaj dostęp [+] do dowolnej aplikacji działającej lokalnie [localuser], która działa jako ja [$ USER]”. „Si” to po prostu klej (patrz xhost(1)i Xsecurity(7)dla dokumentów). Samo to polecenie nie pozwala na żaden dostęp zdalny ani przekazywanie X11 (dla których mechanizm „magicznego ciasteczka” jest zwykle preferowany xhost).
Kevin,

7

Musisz export DISPLAY=:0.0


Nie. Unix nie wymaga eksportu, gdy zmienna jest zapisana w tym samym wierszu. Ta zmienna obowiązuje do końca linii.
Alexis Wilke

Rzeczywiście masz rację.
asoundmove

Ta odpowiedź jest po prostu błędna i powinna zostać usunięta.
Piotr Dobrogost

Nie wiedziałem, że wpisanie DISPLAY =: 0.0 spowoduje ustawienie nazwy zmiennej. Dzięki @asoundmove. Myślę jednak: 0.0 to wartość zmiennej DISPLAY na wyświetlaczu serwera. Jeśli logujesz się z Putty, zmienna DISPLAY powinna wynosić 10 lub więcej. więc powinno być WYŚWIETLANIE =: 10
alpha_989

3

Działa dla mnie, debian wheezy -> ubuntu trusty.

Uwaga: w tym przypadku na serwerze nie działa menedżer wyświetlania, jest to „wirtualna” maszyna wirtualna bez podłączonej karty graficznej lub monitora.

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

Wyświetlacz X na laptopie pokazuje wyjście Xterm działającego na serwerze.

Debuguj za pomocą:

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 rozleje mnóstwo krwawych szczegółów na temat tego, co robi, powinieneś być w stanie zgadnąć, gdzie się utknął - czekając na połączenie lub cokolwiek innego.

W jednej linii ..

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.