Mở một cửa sổ trên màn hình X từ xa (tại sao không thể mở màn hình hiển thị)?


81

Ngày xửa ngày xưa,

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

sau khi ssh vào máy tính để bàn của tôi từ máy tính xách tay của tôi sẽ khiến totem phát movie.avitrên máy tính để bàn của tôi.

Bây giờ nó đưa ra lỗi:

No protocol specified
Cannot open display:

Tôi đã cài đặt lại Debian nén khi nó hoạt động ổn định trên cả hai máy tính và tôi đoán rằng tôi đã phá vỡ cấu hình.

Tôi đã googled về điều này, và không thể cho cuộc sống của tôi tìm ra những gì tôi phải làm.

(VLC có giao diện HTTP hoạt động, nhưng nó không thuận tiện như ssh.)

Vấn đề tương tự phát sinh khi tôi cố gắng chạy nó từ một công việc định kỳ.


1
Máy từ xa của bạn có hiển thị tệp .Xmasterity không? Một câu hỏi rõ ràng khác là - máy chủ ssh và máy khách của bạn có được cấu hình để cho phép chuyển tiếp X không? Bạn đã sử dụng lệnh nào để ssh?
Faheem Mitha

1
Tôi đang cố gắng chuyển tiếp X? Tôi muốn lệnh được thực thi trên máy chủ, không phải máy khách. Lệnh ssh của tôi chỉ là ssh me @ host xác định vị trí .Xmasterity trên máy chủ không khớp với bất kỳ tệp nào.
justin cải xoong

Như Faheem gợi ý, có một thay đổi tốt là vấn đề của bạn là do totemkhông tìm thấy cookie X của bạn và bạn cần đặt thành XAUTHORITYgiá trị phù hợp, nghĩa là giá trị trong phiên thông thường trên máy tính để bàn của bạn. Đọc Linux: wmctrl không thể mở hiển thị khi phiên được bắt đầu qua màn hình ssh + cho một số nền; cũng xem câu trả lời liên quan Khi root tôi có thể khởi chạy chương trình đồ họa trên màn hình người dùng khác không? .
Gilles

1
được rồi, ngồi trước máy tính và gõ echo $ XAUTHORITY cho / var / run / gdm3 / auth-for-jcress-bb32gX / cơ sở dữ liệu trong phiên ssh, gõ echo $ DISPLAY = (đường dẫn ở trên) không giải quyết được vấn đề
justin cải xoong

1
Tôi đổ lỗi cho GDM3, tại sao không thể họ vừa giữ $XAUTHORITYtại ~/.Xauthoritynhư tất cả mọi người hy vọng nó được.
Arrowmaster

Câu trả lời:


78

(Chuyển thể từ Linux: wmctrl không thể mở hiển thị khi phiên được bắt đầu qua màn hình ssh + )

HIỂN THỊ và QUYỀN

Một chương trình X cần hai thông tin để kết nối với màn hình X.

  • Nó cần địa chỉ của màn hình, mà thường là :0khi bạn đang đăng nhập tại địa phương hoặc :10, :11vv khi bạn đang đăng nhập từ xa (nhưng số lượng có thể thay đổi tùy thuộc vào bao nhiêu X kết nối đang hoạt động). Địa chỉ của màn hình thường được chỉ định trong DISPLAYbiến môi trường.

  • Nó cần mật khẩu cho màn hình. Mật khẩu hiển thị X được gọi là cookie ma thuật . Cookie ma thuật không được chỉ định trực tiếp: chúng luôn được lưu trữ trong các tệp thẩm quyền X, đó là một tập hợp các bản ghi của biểu mẫu hình thức :42có cookie cookie 123456. Tệp thẩm quyền X thường được chỉ định trong XAUTHORITYbiến môi trường. Nếu $XAUTHORITYkhông được đặt, chương trình sẽ sử dụng ~/.Xauthority.

Bạn đang cố gắng hành động trên các cửa sổ được hiển thị trên máy tính để bàn của bạn. Nếu bạn là người duy nhất sử dụng máy tính để bàn của bạn, rất có thể tên hiển thị là :0. Việc tìm vị trí của tệp ủy quyền X khó hơn, vì với gdm như được thiết lập trong nén nén Debian hoặc Ubuntu 10.04, nó nằm trong một tệp có tên được tạo ngẫu nhiên. (Trước đây bạn không gặp vấn đề gì vì các phiên bản trước của gdm đã sử dụng cài đặt mặc định, tức là cookie được lưu trữ trong ~/.Xauthority.)

Lấy các giá trị của các biến

Dưới đây là một số cách để có được các giá trị của DISPLAYXAUTHORITY:

  • Bạn có thể bắt đầu một cách có hệ thống một phiên màn hình từ máy tính để bàn của bạn, có thể tự động trong các tập lệnh đăng nhập của bạn (từ ~/.profile; nhưng chỉ thực hiện nếu đăng nhập trong X: test nếu DISPLAYđược đặt thành giá trị bắt đầu :(sẽ bao gồm tất cả các trường hợp bạn có khả năng gặp phải)). Trong ~/.profile:

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

    Sau đó, trong phiên ssh:

    screen -d -r local
    
  • Bạn cũng có thể lưu các giá trị của DISPLAYXAUTHORITYtrong một tệp và gọi lại các giá trị. Trong ~/.profile:

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

    Trong phiên ssh:

    . ~/.local-display-setup.sh
    screen
    
  • Bạn có thể phát hiện các giá trị của DISPLAYXAUTHORITYtừ một quy trình đang chạy. Điều này là khó khăn hơn để tự động hóa. Bạn phải tìm ra PID của một quá trình được kết nối với màn hình mà bạn muốn làm việc, sau đó lấy các biến môi trường từ /proc/$pid/environ( eval export $(</proc/$pid/environ tr \\0 \\n | grep -E '^(DISPLAY|XAUTHORITY)=')).

Sao chép cookie

Một cách tiếp cận khác (theo gợi ý của Arrowmaster ) là không cố lấy giá trị $XAUTHORITYtrong phiên ssh, mà thay vào đó để làm cho phiên X sao chép cookie của nó vào ~/.Xauthority. Vì cookie được tạo mỗi lần bạn đăng nhập, nên không có vấn đề gì nếu bạn giữ các giá trị cũ ~/.Xauthority.

Có thể có một vấn đề bảo mật nếu thư mục chính của bạn có thể truy cập qua NFS hoặc hệ thống tệp mạng khác cho phép quản trị viên từ xa xem nội dung của nó. Họ vẫn cần kết nối với máy của bạn bằng cách nào đó, trừ khi bạn đã bật kết nối X TCP (mặc định Debian tắt chúng). Vì vậy, đối với hầu hết mọi người, điều này không áp dụng (không có NFS) hoặc không phải là vấn đề (không có kết nối X TCP).

Để sao chép cookie khi bạn đăng nhập vào phiên X của máy tính để bàn, hãy thêm các dòng sau vào ~/.xprofilehoặc ~/.profile(hoặc một số tập lệnh khác được đọc khi bạn đăng nhập):

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

¹ Về nguyên tắc này thiếu đúng đắn trích dẫn, nhưng trong trường hợp cụ thể này $DISPLAY$XAUTHORITYsẽ không chứa bất kỳ metacharater vỏ.


2
Một cách để tự động hóa việc này là tạo một ~/.xprofilecái chỉ nên chạy trong lần đăng nhập X và tạo nó / cập nhật ~/.Xauthorityvới thông tin chính xác. Một liên kết tượng trưng là đủ?
Arrowmaster

@Arrowmaster: Đó là một gợi ý tốt. Tôi đã không nghĩ về nó. Nó sẽ không hoạt động trong mọi trường hợp, ví dụ nếu bạn đăng nhập vào nhiều phiên X (trên các thiết bị đầu cuối khác nhau, với vnc, thì), nhưng nó đơn giản và đủ tốt để sử dụng thông thường. Một liên kết tượng trưng là cách tốt nhất. Hmm, thực sự có một cách đơn giản hơn, tốt hơn: bạn có thể sao chép thông tin vào ~/.Xauthority.
Gilles

1
Sẽ đặt một cái gì đó như xauth extract - $DISPLAY | xauth -f "$HOME/.Xauthority" merge -trong việc ~/.xprofilegiải quyết trường hợp của nhiều $ HIỂN THỊ?
Arrowmaster

@Arrowmaster: Bạn thấy vấn đề gì với nhiều màn hình? Mặc dù về nguyên tắc, mã của bạn có thể sạch hơn một chút vì bạn chỉ trích xuất thông tin về màn hình mà bạn quan tâm, tôi không thấy có gì sai với sự hợp nhất đơn giản trong trường hợp của người hỏi hoặc thực sự bên ngoài các trường hợp rất bất thường.
Gilles

1
Đọc môi trường trong một quy trình hiện có được kết nối với màn hình là điều bất ngờ thú vị. Tôi hết lòng tán thành. Unix.SE cần một huy hiệu Evil Genius ™ cho việc này.
derobert

19

Tôi đã giải quyết vấn đề này bằng cách thêm

xhost +si:localuser:$USER

để ~/.xprofile. Tôi không biết điều này có an toàn không (tôi rất muốn nghe những gì dân gian hiểu biết hơn), nhưng tôi đoán rằng nó tốt hơn nhiều so với tắt điều khiển truy cập (với xhost +) như thường được đề xuất khi bạn google cho vấn đề này.


1
localuserđịa chỉ máy chủ giải thích là hoàn toàn an toàn. Debian thậm chí còn làm điều này theo mặc định như là một phần của quá trình đăng nhập (in /etc/X11/Xsession.d/35x11-common_xhost-local). Xem trang người đàn ông Xsecurity để biết thêm chi tiết.
Sam Morris

Nếu bạn đang sử dụng mạng LAN, xhost +có lẽ là đủ trong hầu hết các trường hợp ...
Alexis Wilke

Bạn có thể giải thích ý nghĩa của lệnh này không?
alpha_989

@ alpha_989: Có nghĩa là "Cấp quyền truy cập [+] cho bất kỳ ứng dụng [localuser] nào đang chạy cục bộ đang chạy như tôi [$ USER]." "Si" chỉ là chất keo (xem xhost(1)Xsecurity(7)cho các tài liệu). Chính nó, lệnh này không cho phép bất kỳ loại truy cập từ xa hoặc chuyển tiếp X11 nào (mà cơ chế "cookie ma thuật" thường được ưa thích hơn xhost).
Kevin

7

Bạn cần phải export DISPLAY=:0.0


Không. Unix không yêu cầu xuất khi biến được viết trên cùng một dòng. Biến đó có hiệu lực cho đến khi dòng kết thúc.
Alexis Wilke

Thật vậy, bạn đã đúng.
asoundmove

Câu trả lời này là sai rõ ràng và nên được xóa.
Piotr Dobrogost

Không biết chỉ cần gõ HIỂN THỊ =: 0,0 sẽ đặt tên biến. Cảm ơn @asoundmove. Tuy nhiên, tôi nghĩ: 0,0 là giá trị cho biến HIỂN THỊ ở màn hình máy chủ. Nếu bạn đang đăng nhập từ Putty, thì HIỂN THỊ biến đổi nên từ 10 trở lên. vì vậy nó phải là HIỂN THỊ =: 10
alpha_989

3

Làm việc cho tôi, debian wheezy -> ub Ubuntu đáng tin cậy.

Lưu ý: trong trường hợp này, máy chủ không chạy trình quản lý hiển thị, đó là máy ảo 'không đầu' không có card đồ họa hoặc màn hình đi kèm.

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

Màn hình X trên máy tính xách tay hiển thị đầu ra của xterm đang chạy trên máy chủ.

Gỡ lỗi bằng cách sử dụng:

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 sẽ tiết lộ vô số thông tin chi tiết về những gì nó đang làm, bạn sẽ có thể đoán nó bị kẹt ở đâu - chờ kết nối hoặc bất cứ điều gì.

Trong một dòng ..

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.