【问题标题】:How to determine from a python application if X server/X forwarding is running?如何从 python 应用程序确定 X 服务器/X 转发是否正在运行?
【发布时间】:2012-08-25 14:05:56
【问题描述】:

我正在编写一个 Linux 应用程序,它使用 PyQt4 作为 GUI 并且仅在远程会话期间使用
(ssh -XY / vnc)。

所以有时用户可能会忘记使用 X 转发参数运行 ssh,或者由于某种原因 X 转发将不可用。在这种情况下,应用程序严重崩溃(不幸的是,我不得不使用包装在 python 中的旧 C++ 库,如果应用程序崩溃,它会完全弄乱用户的当前会话)。

我不能使用其他东西,所以我的想法是在加载该库之前检查 X 转发是否可用。但是我不知道该怎么做。

我通常使用 xclock 来检查我的会话是否启用了 X 转发,但使用 xclock 听起来像是一个很大的解决方法。

添加
如果可能的话,我想使用另一种方法,而不是创建一个空的 PyQt 窗口并捕获异常。

【问题讨论】:

    标签: python ssh pyqt4 xserver


    【解决方案1】:

    检查 $DISPLAY 环境变量是否已设置 - 如果他们没有使用 ssh -X,它将为空(而不是包含类似 localhost:10 的内容)。

    【讨论】:

    • 这就是我一直在寻找的东西,简洁明了,谢谢。
    • 如果他们使用ssh -X 但没有运行X 服务器会怎样?从我的随意测试看来,$DISPLAY 似乎不会被设置,但这是真的吗?
    【解决方案2】:

    如前所述,您可以检查 DISPLAY 环境变量:

    >>> os.environ['DISPLAY']
    'localhost:10.0'
    

    如果您愿意,实际上可以连接到显示端口以查看 sshd 正在监听它:

    import os
    import socket
    
    def tcp_connect_to_display():
            # get the display from the environment
            display_env = os.environ['DISPLAY']
    
            # parse the display string
            display_host, display_num = display_env.split(':')
            display_num_major, display_num_minor = display_num.split('.')
    
            # calculate the port number
            display_port = 6000 + int(display_num_major)
    
            # attempt a TCP connection
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                    sock.connect((display_host, display_port))
            except socket.error:
                    return False
            finally:
                sock.close()
            return True
    

    这依赖于使用端口 6000 + 显示编号的标准 X 配置。

    【讨论】:

    • 我会记住这个解决方案,也许它会在未来证明有用,谢谢。
    【解决方案3】:

    与您的 xclock 解决方案类似,我喜欢运行 xdpyinfo 并查看它是否返回错误。

    【讨论】:

    • 这很好,因为如果客户端没有运行 X-server,它会以零退出(对于忘记启动 xming 的 Windows 用户来说很常见)。我将在 bash 脚本中使用它,谢谢。
    【解决方案4】:

    X-Server 可以使用 TkInter 进行检查,如下例所示(但 PyQt4 应该有类似的方法):

    import time
    import sys
    try:
        import Tkinter as tk
    except ImportError:
        import tkinter as tk
    
    while True:
        try:
            root = tk.Tk()
            break
        except tk.TclError as e:
            if "$DISPLAY" in str(e):
                print("$DISPLAY not set. Exiting.")
                sys.exit(1)
            print("Waiting for X server to start...")
            time.sleep(1)
    
    print("X server running")
    root.destroy()
    sys.exit(0)
    

    这将检查$DISPLAY 设置、X-Server 进程和相关的xhost 授权(但使用TkInter 而不是PyQt4)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多