เปิดหน้าต่างบนจอแสดงผล X ระยะไกล (ทำไม“ ไม่สามารถเปิดจอแสดงผล”)


81

กาลครั้งหนึ่ง,

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

หลังจากเข้าสู่เดสก์ท็อปจากแล็ปท็อปของฉันจะทำให้โทเท็มเล่นmovie.aviบนเดสก์ท็อป

ตอนนี้มันทำให้เกิดข้อผิดพลาด:

No protocol specified
Cannot open display:

ฉันติดตั้ง Debian squeeze ใหม่อีกครั้งเมื่อมันเสถียรในคอมพิวเตอร์ทั้งสองเครื่องและฉันเดาว่าตัวเองยากจน config

ฉันทำสิ่งนี้และไม่สามารถใช้ชีวิตของฉันเพื่อค้นหาสิ่งที่ฉันควรจะทำ

(VLC มีอินเตอร์เฟส HTTP ที่ใช้งานได้ แต่ไม่สะดวกเท่ากับ ssh)

ปัญหาเดียวกันเกิดขึ้นเมื่อฉันพยายามเรียกใช้จากงาน cron


1
เครื่องระยะไกลของคุณแสดงไฟล์. Xauthority หรือไม่ คำถามที่ชัดเจนอื่น ๆ คือ - เซิร์ฟเวอร์ ssh และไคลเอ็นต์ของคุณได้รับการกำหนดค่าให้อนุญาตการส่งต่อ X หรือไม่ คุณใช้คำสั่ง ssh อะไร?
Faheem Mitha

1
ฉันพยายามส่งต่อ X หรือไม่ ฉันต้องการให้คำสั่งถูกเรียกใช้งานบนโฮสต์ไม่ใช่ไคลเอ็นต์ คำสั่ง ssh ของฉันเป็นเพียง ssh me @ host locate. Xauthority บนโฮสต์คอมพิวเตอร์ไม่ตรงกับไฟล์ใด ๆ
จัสตินหยุด

ดังที่ Faheem เสนอแนะมีการเปลี่ยนแปลงที่ดีที่ปัญหาของคุณเกิดจากการtotemไม่พบคุกกี้ X ของคุณและคุณจำเป็นต้องตั้งค่าXAUTHORITYให้เหมาะสมเช่นค่าในเซสชันปกติบนเดสก์ท็อปของคุณ อ่านLinux: wmctrl ไม่สามารถเปิดการแสดงผลเมื่อเริ่มต้นเซสชันผ่าน ssh + หน้าจอสำหรับพื้นหลังบางอย่าง ดูคำตอบที่เกี่ยวข้องเช่นกันฉันจะเปิดโปรแกรมกราฟิกบนเดสก์ท็อปของผู้ใช้คนอื่นได้อย่างไร .
Gilles

1
ไม่เป็นไรร่างกายนั่งอยู่ที่คอมพิวเตอร์และพิมพ์ echo $ XAUTHORITY ให้ / var / run / gdm3 / auth-for-jcress-bb32gX / ฐานข้อมูลในเซสชัน ssh พิมพ์ echo $ DISPLAY = (เส้นทางด้านบน) ไม่ได้แก้ปัญหา
จัสตินหยุด

1
ฉันโทษ GDM3 ทำไมไม่สามารถที่พวกเขาได้เก็บไว้เพียง$XAUTHORITYที่~/.Xauthorityเหมือนคนคาดหวังว่ามันจะ
Arrowmaster

คำตอบ:


78

(ดัดแปลงจากLinux: wmctrl ไม่สามารถเปิดการแสดงผลได้เมื่อเซสชันเริ่มต้นผ่านหน้าจอ ssh + )

การแสดงผลและหน่วยงาน

โปรแกรม X ต้องการข้อมูลสองชิ้นเพื่อเชื่อมต่อกับจอแสดงผล X

  • มันต้องอยู่ของจอแสดงผลซึ่งโดยปกติ:0เมื่อคุณเข้าสู่ระบบในท้องถิ่นหรือ:10, :11ฯลฯ เมื่อคุณเข้าสู่ระบบจากระยะไกล ( แต่จำนวนจะเปลี่ยนไปขึ้นอยู่กับจำนวนการเชื่อมต่อ X มีการใช้งาน) ปกติแล้วที่อยู่ของจอแสดงผลจะระบุไว้ในDISPLAYตัวแปรสภาพแวดล้อม

  • มันต้องการรหัสผ่านสำหรับการแสดงผล รหัสผ่าน X จอแสดงผลจะเรียกว่าคุกกี้มายากล ไม่ได้ระบุคุกกี้เวทย์โดยตรง: พวกมันจะถูกเก็บไว้ในไฟล์ X Authority เสมอซึ่งเป็นชุดของเร็กคอร์ดของฟอร์ม“ display :42มีคุกกี้123456” โดยปกติไฟล์สิทธิ X จะระบุไว้ในXAUTHORITYตัวแปรสภาพแวดล้อม หากไม่มีการตั้งค่าโปรแกรมใช้$XAUTHORITY~/.Xauthority

คุณกำลังพยายามที่จะทำงานกับหน้าต่างที่ปรากฏบนเดสก์ท็อป :0หากคุณเป็นเพียงคนเดียวที่ใช้เครื่องคอมพิวเตอร์ของคุณก็มีโอกาสมากที่ชื่อจอแสดงผลเป็น การค้นหาตำแหน่งของไฟล์ X Authority นั้นยากกว่าเพราะด้วย gdm ตามที่ตั้งไว้ภายใต้ Debian squeeze หรือ Ubuntu 10.04 มันอยู่ในไฟล์ที่มีชื่อที่สร้างแบบสุ่ม (คุณไม่มีปัญหามาก่อนเพราะ gdm รุ่นก่อนหน้าใช้การตั้งค่าเริ่มต้นเช่นคุกกี้ที่เก็บไว้~/.Xauthority)

รับค่าของตัวแปร

ต่อไปนี้เป็นวิธีการรับค่าDISPLAYและXAUTHORITY:

  • คุณสามารถเริ่มเซสชันหน้าจอจากเดสก์ท็อปของคุณอย่างเป็นระบบโดยอัตโนมัติในสคริปต์การเข้าสู่ระบบของคุณ (จาก~/.profileแต่ทำได้เฉพาะเมื่อเข้าสู่ระบบภายใต้ X: ทดสอบว่าDISPLAYตั้งค่าเป็นค่าเริ่มต้นด้วย:(ซึ่งควรครอบคลุมทุกกรณี พบ)) ใน~/.profile:

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

    จากนั้นในเซสชัน ssh:

    screen -d -r local
    
  • คุณสามารถบันทึกค่าDISPLAYและXAUTHORITYในไฟล์และเรียกคืนค่าต่างๆ ใน~/.profile:

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

    ในเซสชัน ssh:

    . ~/.local-display-setup.sh
    screen
    
  • คุณสามารถตรวจสอบค่าของDISPLAYและXAUTHORITYจากกระบวนการทำงาน นี่เป็นเรื่องยากที่จะทำให้เป็นอัตโนมัติ คุณต้องคิด PID ของกระบวนการที่เชื่อมต่อกับจอแสดงผลที่คุณต้องการทำงานจากนั้นรับตัวแปรสภาพแวดล้อมจาก/proc/$pid/environ( eval export $(</proc/$pid/environ tr \\0 \\n | grep -E '^(DISPLAY|XAUTHORITY)=')¹)

คัดลอกคุกกี้

อีกวิธีหนึ่ง (ตามคำแนะนำโดยArrowmaster ) คือการไม่พยายามที่จะได้รับค่าของ$XAUTHORITYในเซสชั่น SSH ~/.Xauthorityแต่แทนที่จะเพื่อให้เซสชั่นเอ็กซ์คัดลอกคุกกี้ของมันเข้าไป ~/.Xauthorityตั้งแต่คุกกี้จะถูกสร้างขึ้นในแต่ละครั้งที่คุณเข้าสู่ระบบก็ไม่ได้เป็นปัญหาถ้าคุณเก็บค่าค้างใน

อาจมีปัญหาด้านความปลอดภัยหากโฮมไดเรกทอรีของคุณสามารถเข้าถึงได้ผ่าน NFS หรือระบบไฟล์เครือข่ายอื่นที่อนุญาตให้ผู้ดูแลระบบระยะไกลสามารถดูเนื้อหาได้ พวกเขายังคงต้องเชื่อมต่อกับเครื่องของคุณยกเว้นว่าคุณได้เปิดใช้งานการเชื่อมต่อ X TCP (Debian จะปิดใช้งานตามค่าเริ่มต้น) ดังนั้นสำหรับคนส่วนใหญ่สิ่งนี้อาจใช้ไม่ได้ (ไม่มี NFS) หรือไม่มีปัญหา (ไม่มีการเชื่อมต่อ X TCP)

หากต้องการคัดลอกคุกกี้เมื่อคุณเข้าสู่เซสชัน X บนเดสก์ท็อปของคุณให้เพิ่มบรรทัดต่อไปนี้ลงใน~/.xprofileหรือ~/.profile(หรือสคริปต์อื่นที่อ่านเมื่อคุณลงชื่อเข้าใช้):

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

¹ ในหลักการนี้ขาดเหมาะสม quoting แต่ในกรณีนี้โดยเฉพาะ$DISPLAYและ$XAUTHORITYจะไม่ประกอบด้วย metacharacter เปลือกใด ๆ


2
วิธีหนึ่งในการทำให้สิ่งนี้เป็นแบบอัตโนมัติคือการสร้างสิ่ง~/.xprofileที่ควรรันในระหว่างการเข้าสู่ระบบ X และให้มันสร้าง / อัพเดต~/.Xauthorityด้วยข้อมูลที่ถูกต้อง ลิงก์สัญลักษณ์จะเพียงพอหรือไม่
Arrowmaster

@ Arrowmaster: นั่นเป็นคำแนะนำที่ดี ฉันไม่ได้คิดถึงมัน มันจะไม่ทำงานในทุกกรณีเช่นหากคุณลงชื่อเข้าใช้มากกว่าหนึ่งเซสชัน X (ในเทอร์มินัลต่าง ๆ ด้วย vnc, ... ) แต่มันง่ายและดีพอสำหรับการใช้งานทั่วไป ลิงก์สัญลักษณ์เป็นวิธีที่ดีที่สุด อืมจริงๆแล้วมันมีวิธีที่ดีกว่าและเรียบง่าย: คุณสามารถคัดลอกข้อมูลลงไป~/.Xauthorityได้
Gilles

1
จะวางบางอย่างเช่นxauth extract - $DISPLAY | xauth -f "$HOME/.Xauthority" merge -ในการ~/.xprofileแก้กรณีของ $ DISPLAY หลายรายการหรือไม่
Arrowmaster

@Arrowmaster: คุณเห็นปัญหาอะไรกับจอแสดงผลหลายจอ? ในขณะที่รหัสของคุณอาจจะดูสะอาดกว่าเดิมเล็กน้อยเนื่องจากคุณเพียงดึงข้อมูลเกี่ยวกับจอแสดงผลที่คุณสนใจ แต่ฉันไม่เห็นอะไรผิดปกติกับการรวมง่าย ๆ ในกรณีของผู้ถามหรืออยู่นอกสถานการณ์ที่ผิดปกติมาก
Gilles

1
การอ่านสภาพแวดล้อมของกระบวนการที่มีอยู่ซึ่งเชื่อมต่อกับจอแสดงผลนั้นเป็นสิ่งที่ไม่คาดคิดว่าเป็นสิ่งที่น่ายินดีอย่างยิ่ง ฉันอนุมัติสุดใจ Unix.SE ต้องการตรา Evil Genius ™สำหรับสิ่งนี้
Derobert

19

ฉันแก้ไขปัญหานี้ด้วยการเพิ่ม

xhost +si:localuser:$USER

~/.xprofileไปยัง ฉันไม่รู้ว่านี่ปลอดภัยหรือไม่ (ฉันสนใจมากที่จะได้ยินว่าชาวบ้านมีความรู้มากกว่านี้) แต่ฉันเดาว่าจะดีกว่าการปิดการควบคุมการเข้าถึง (พร้อมxhost +) ตามที่แนะนำโดยทั่วไปเมื่อคุณ google สำหรับปัญหานี้


1
localuserที่อยู่ที่ตีความโดยเซิร์ฟเวอร์นั้นปลอดภัยอย่างสมบูรณ์ Debian ทำสิ่งนี้เป็นค่าเริ่มต้นโดยเป็นส่วนหนึ่งของกระบวนการเข้าสู่ระบบ (ใน/etc/X11/Xsession.d/35x11-common_xhost-local) ดูหน้าXsecurityสำหรับรายละเอียดเพิ่มเติม
Sam Morris

หากคุณอยู่ในระบบ LAN xhost +น่าจะเพียงพอในกรณีส่วนใหญ่ ...
อเล็กซิส Wilke

คุณจะสามารถอธิบายความหมายของคำสั่งนี้ได้หรือไม่
alpha_989

@ alpha_989: มันหมายถึง "ให้สิทธิ์การเข้าถึง [+] กับแอปพลิเคชัน [localuser] ใด ๆ ที่ทำงานในพื้นที่ซึ่งกำลังทำงานเหมือนฉัน [$ USER]" "si" เป็นเพียงกาว (ดูxhost(1)และXsecurity(7)สำหรับเอกสาร) ด้วยตัวเองคำสั่งนี้ไม่อนุญาตให้มีการเข้าถึงระยะไกลหรือการส่งต่อ X11 ใด ๆ (ซึ่งเป็นที่ต้องการกลไก "คุกกี้มายากล" มากกว่าxhost)
เควิน

7

คุณจำเป็นต้อง export DISPLAY=:0.0


ไม่ได้ Unix ไม่ต้องการการส่งออกเมื่อมีการเขียนตัวแปรในบรรทัดเดียวกัน ตัวแปรนั้นจะมีผลจนกว่าจะสิ้นสุดบรรทัด
Alexis Wilke

แน่นอนว่าคุณพูดถูก
asoundmove

คำตอบนี้ผิดอย่างชัดเจนและควรลบ
Piotr Dobrogost

ไม่ทราบเพียงพิมพ์ DISPLAY =: 0.0 จะตั้งชื่อตัวแปร ขอบคุณ @asoundmove อย่างไรก็ตามฉันคิดว่า: 0.0 คือค่าสำหรับตัวแปร DISPLAY ที่เซิร์ฟเวอร์แสดง หากคุณกำลังเข้าสู่ระบบจาก Putty, DISPLAY ตัวแปรควร 10 หรือสูงกว่า ดังนั้นจึงควรเป็น DISPLAY =: 10
alpha_989

3

ใช้งานได้สำหรับฉันเดเบียน wheezy -> ubuntu trusty

หมายเหตุ: ในกรณีนี้เซิร์ฟเวอร์ไม่ได้ใช้งานตัวจัดการการแสดงผลมันเป็นเครื่องเสมือน 'หัวขาด' ที่ไม่มีการ์ดกราฟิกหรือจอภาพติดอยู่

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

X display บนแล็ปท็อปแสดงเอาต์พุตของ xterm ที่ทำงานบนเซิร์ฟเวอร์

แก้ไขข้อบกพร่องโดยใช้:

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 จะทำให้รายละเอียดเต็มไปด้วยเลือดเต็มไปด้วยสิ่งที่กำลังทำอยู่คุณควรคาดเดาได้ว่าจะติดอยู่ที่ไหน - รอการเชื่อมต่อหรืออะไรก็ตาม

ในหนึ่งบรรทัด ..

ssh -C -R 6000:127.0.0.1:6000 alice@server "DISPLAY=:0.0 xterm"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.