$DISPLAY环境变量是什么?

我对shell脚本编程还很陌生。我不明白$DISPLAY环境变量是什么意思。
我使用的是Ubuntu 13.10操作系统,使用的是/bin/bash shell,并且有两个显示器。
以下是我的问题:
  1. 在我的机器上(两个显示器上),命令echo $DISPLAY会打印出:0.0。这代表什么意思?

  2. 在哪些情况下$DISPLAY变量会为空或为NULL?

  3. 是否有任何关于此主题的文章或教程可供参考?


6今天 echo $DISPLAY 打印的是 :0 而不是 :0.0 - Chandrayya G K
1请检查此链接以帮助解决空白或错误问题:http://askubuntu.com/questions/432610/how-to-know-which-processes-have-the-display-variable-set - Maythux
5个回答

在X窗口系统中,魔术词是DISPLAY。一个显示器(简化)包括:
- 一个键盘, - 一个鼠标, - 一个屏幕。
显示器由一个服务器程序管理,称为X服务器。该服务器向连接到它的其他程序提供显示功能。
远程服务器通过DISPLAY环境变量的定义来知道它必须重定向X网络流量的位置,该变量通常指向位于您本地计算机上的X显示服务器。
显示环境变量的值为:
hostname:D.S

在哪里:

主机名是运行X服务器的计算机的名称。省略主机名意味着本地主机。

D是一个序列号(通常为0)。如果有多个显示器连接到一台计算机上,可以进行变化。

S是屏幕编号。一个显示器实际上可以有多个屏幕。通常情况下,只有一个屏幕,默认为0。

值的示例

localhost:4
google.com:0
:0.0

hostname:D.S 意味着主机 hostname 上显示器 D 的屏幕 S; 此显示器的 X 服务器正在 TCP 端口 6000+D 监听。

host/unix:D.S 意味着主机 host 上显示器 D 的屏幕 S; 此显示器的 X 服务器正在 UNIX 域套接字 /tmp/.X11-unix/XD 上监听(因此仅可从主机访问)。

:D.S 等同于 host/unix:D.S,其中 host 是本地主机名。

:0.0 表示我们正在谈论连接到您本地主机上第一个显示器的第一个屏幕

请在 此处 support.objectplanet.com此处 superuser.com此处 docstore.mik.ua 阅读更多内容。

来自 X(7) man 页面:

从用���的角度来看,每个X服务器都有一个显示名称的形式: hostname:displaynumber.screennumber 应用程序使用这些信息来确定应该如何连接到服务器和默认情况下应该使用哪个屏幕(对于具有多个显示器的显示器): 主机名指定物理连接到显示器的机器的名称。如果没有提供主机名,则将使用与同一台计算机上的服务器进行通信的最有效方法。 显示号通常用于表示共享公共键盘和指针(鼠标、平板等)的显示器集合。大多数工作站往往只有一个键盘,因此只有一个显示器。然而,较大的多用户系统经常有几个显示器,以便可以同时完成多个人的图形工作。为了避免混淆,在启动该显示器的X服务器时,给该机器上的每个显示器分配一个显示号(从0开始)。显示号必须始终在显示名称中给出。 某些显示器在两个或更多监视器之间共享单个键盘和指针。由于每个监视器都有自己的窗口集,所以在启动该显示器的X服务器时,为每个屏幕分配一个屏幕编号(从0开始)。如果没有给出屏幕编号,将使用屏幕0。

1当这个 $DISPLAY 为空或者空白时。 - Chandrayya G K
通常情况下,除非您的显示器出现问题,否则不会发生这种情况。大多数情况下,重新启动显示管理器可以解决问题。但这并不是默认操作。 - Maythux
http://askubuntu.com/questions/432610/how-to-know-which-processes-have-the-display-variable-set - Maythux
例如,当我不使用任何桌面环境,如GNOME或KDE,而是直接通过TTY登录(如/dev/tty1),我得到了空白的$DISPLAY - Franklin Yu
3@Maythux 有时候屏幕号码在为0时似乎被省略了。我的GNOME显示:0作为$DISPLAY - Franklin Yu
以防有人疑惑:端口6000在此提到(https://www.x.org/docs/XProtocol/proto.pdf),附录B,连接设置章节,第113页:“对于TCP连接,给定主机上的显示器从0开始编号,并且显示N的服务器侦听和接受使用端口6000 + N的连接。” - yaobin
那么,: 到底是什么意思呢?它和 :0.0 是等价的吗? - user222949

现有的答案未能涵盖更广泛的情况。
如果您没有使用图形环境(即在系统控制台上登录,没有窗口等;或者通过SSH或类似方式从纯文本终端远程登录,例如从运行PuTTY的Windows计算机登录),则不涉及GUI,并且DISPLAY通常未设置。您与计算机进行通信的唯一方式是命令行(尽管可能有办法转到GUI会话,如果您知道如何操作)。
如果您在带有图形界面的控制台上登录(在Ubuntu上,通常使用GDM欢迎程序)或使用图形终端(例如从运行eXceed或mobaX的Windows计算机,或远程桌面软件如VNC客户端),DISPLAY变量将由管理您的图形会话的程序设置,以指示图形客户端连接到哪些输入/输出设备。

传统上,Ubuntu 计算机上的图形用户界面 (GUI) 运行的是 X.org,这是一个 X11 实现。然而,最近由 Canonical 推出了一种现代化的替代品叫做 Mir;而更近期,我相信 Mir 将被放弃,转而采用一个名为 Wayland 的项目,其目标与之类似。这些替代方案旨在减少完整 X11 栈的复杂性,我们不会在此展开讨论 —— 它们遵循相同的 DISPLAY 约定,这正是我们在此讨论的内容。

在X11上,DISPLAY的主机部分可以是远程服务器,您可以将Ubuntu计算机用作访问该远程服务器上的文件和程序的"图形终端"(在这种情况下,您的计算机是为运行在远程服务器上的"客户端"程序提供键盘、鼠标和一个或多个显示设备的"服务器")。更常见的情况是,X11(或Mir、Wayland)服务器和客户端程序(如桌面管理器和各种图形客户端,如Web浏览器、电子邮件客户端、日历程序等)都在您的计算机上运行。这由DISPLAY值的"服务器"部分表示,在后一种情况下,通常为空(这意味着默认值localhost)。
一个X11服务器可以运行一个或多个图形会话--例如,您的控制台登录和一个远程VNC会话可以同时运行。在这种情况下(如果它们由同一个X11服务器实例管理),您在X11术语中拥有多个"显示"。实际上,一个会话(一个登录事件和从此生成的桌面实例)在X11中就是一个显示。
一个这样的显示器可以有一个或多个屏幕。传统上,这意味着一个监视器,尽管最初的架构有一些不幸的特点,比如无法将窗口从一个屏幕移动到另一个屏幕。像Xinerama和Xrandr这样的附加组件进一步混淆了情况,以至于一个屏幕经常以各种方式连接多个监视器。
如果你玩过多屏系统,你可能发现你可以以各种方式排列监视器,并最终得到一个矩形区域,其中你的监视器显示其中的一部分,而其他部分没有分配给任何监视器。这就是X11创建的“屏幕”,如果你有多个显示卡,你可以拥有多个这样的屏幕,每个屏幕分配给一个或多个监视器(或者理论上,运行时没有监视器;Xvfb利用这一点允许你在没有任何监视器的情况下运行X11,只需将GUI映射到内存区域以供任何目的使用)。

Mir确实已经和Unity一起被抛弃了。很长一段时间里,lightdm而不是gdm是默认选项,但也许你回答中的这部分又变得正确了,就像在Unity崛起之前一样!我使用MATE,所以无法轻易检查... - Zanna
1我在控制台上运行Linux(没有Windows),这就解释了一切。其实很有道理 :p - Jean-Francois T.
你知道DISPLAY变量是如何设置的以及它在哪里设置吗?因为我知道这个变量在任何文件中都不存在。我猜想它是被每个进程继承的。例如,进程/usr/bin/plasmashell已经设置了这个变量,而它的所有子进程(比如/usr/bin/plasma-systemmonitor/usr/bin/ksysguardd)也会有相同的变量设置。 - Edgar Magallon
1X11服务器(或者说,嗯,服务器客户端?显示管理器,我猜)在创建会话时为您设置它。 - tripleee

echo $DISPLAY会在我的机器上打印:0.0(在两个显示器上)。这是什么意思?
:0.0表示显示器编号为0,屏幕编号为0。
在哪种情况下$DISPLAY会为空或NULL?
当您的$DISPLAY出现错误时,通常不会发生这种情况。
有关此问题的文章或教程吗?
可以在以下位置找到一些教程和资源:
- [链接1:pic.dhe.ibm.com](1) - [链接2:unix.com/unix-dummies-questions-answers](2) - [链接3:superuser.com/questions/368530](3)

https://help.ubuntu.com/community/EnvironmentVariables中:

变量- DISPLAY

值示例:

:0.0
localhost:10.0
terminal01:0.0

这个变量用于指示图形应用程序在哪里显示实际的图形用户界面,其值由3部分组成:主机名后跟一个冒号(:),显示号后跟一个点(.)和屏幕号。
主机名部分可用于将图形输出发送到网络上的远程计算机。当输出用于在本地计算机上运行的X服务器时,可以省略主机名部分。显示号允许在同一台计算机上运行的多个X服务器中进行选择(Ubuntu使用多个X服务器以启用多个图形桌面会话)。
尽管屏幕号用于在同一X服务器管理的多个物理屏幕中进行选择,但现在很少将其设置为除了"0"之外的其他值。现在很少需要手动设置"DISPLAY"环境变量的值,因为许多应用程序(如"GDM"和"SSH")在需要时可以自动智能地调整它。

最近我一直在为自动在特定时间启动Firefox的一些脚本编写,以提醒我打卡和下班,因为我一直在家工作。我发现DISPLAY变量是由显示管理器确定的,例如GDM3、LightDM等。我还发现:0:1由AutomaticLogin确定。在GDM3中,如果我禁用了AutomaticLogin,那么我的DISPLAY变量就是:1。如果我启用了AutomaticLogin,DISPLAY现在就是:0。无论我连接多少个显示器到我的系统上,这些数字都不会改变。

这个问题的重要性在于我使用在特定时间启动一个脚本来启动Firefox。实际上,没有设置变量,事实上它们非常有限,所以在我的脚本顶部,在SheBang行之后,我有一行代码来导出我的类型。如果在由调用的脚本中不导出,Firefox将无法启动,而是会显示错误,因为没有设置。
#This line checks if automatic login is disabled in gdm3 and sets DISPLAY.
grep "# AutomaticLogin" /etc/gdm3/custom.conf >/dev/null && export DISPLAY=":1" || export DISPLAY=":0"