特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束。如果某条评论中出现了两个$,MathJax 会将两个$之间的内容按照数学公式进行排版,从而导致评论区格式混乱。如果大家的评论中用到了$,但是又不是为了使用数学公式,就请使用\$转义一下,谢谢。

想从头阅读该系列吗?下面是传送门:

前言##

大名鼎鼎的 X Window 大家肯定不陌生。都知道它是 Unix/Linux 下面的窗口系统,也都知道它基于 Server/Clinet 架构。在网上随便搜一搜,也可以找到不少 X Window 的介绍。有不少文章为了给用户留一个直观的印象,往往先让系统进入纯文本界面,然后使用 startx 来启动图形界面,或者直接使用 X 来启动 X Server,再然后运行一个 xterm 来做示范。我觉得以上这些文章对 X Window 的理解有限,不够深入。所以,我这里写一篇《X Window 的奥秘》,以最新的 Ubuntu-18.10 Desktop 为例,展示如何学习 X Window。

10 月是一个比较开心的月份。在这个月中,陆续发布了最新的 Ubuntu 18.10 和 Fedora 29,还有人在我的博客中问关于 CentOS 7 的问题。CentOS 7 固然是一个优秀的发行版,但并不是作为桌面系统的首选,Gnome 的版本太旧,官方仓库中的软件包也不够丰富,美化起来比较困难。在这一篇中,我要展示远程连接 X Server 的操作,需要两个外观差距稍微大一点的 Linux 桌面系统,所以选择了 CentOS 7 和 Ubuntu 18.10。

Ubuntu 18.10 这次外观大变样,使用了 Yaru 主题,下面的截图展示了其中 Terminal 和 GVim 的外观:

而 CentOS 7 默认的外观实在太丑,所以我给他换上了最流行的 adapta-gtk-theme 和 paper-icon-theme,下面的截图展示了其中 Terminal 和 GVim 的外观:

这两种风格应该是比较好区分的,在后文中,很容易通过外观来判断一个 GUI 程序究竟来自于哪一个系统。

了解自己机器上的 X Window##

X Window 其实是一种规范,它有很多不同的实现,在 Linux 系统下最流行的是实现 Xorg 和 XFree86,微软 Windows 系统下也有 X Window 的实现,苹果的 Mac 也是 X Window 的一种实现。要了解自己机器上运行的 X Window 究竟是哪一个,可以使用查看进程的ps命令,如下图:

从上图可以看出,Ubuntu 18.10 使用的 X Window 是 Xorg。如果使用ps -ef命令,还可以看到 Xorg 运行时的命令行参数。

想了解 X Window,下面这些文档需要看一遍先:

下面来说一下也许是众所周知的基础知识:X Window 是一个分层的架构,它分为 Serve 和 Client。X Server 负责图形界面的显示,(也负责用户的输入),而Client 程序需要连接到 X Server,然后请求 X Server 绘制图形界面,同时从 X Server 接受用户的输入。在桌面系统上,X Server 和 Client 程序往往安装在同一台机器上,日常使用基本感觉不到它是分层的。但是很显然,X Server 和 Client 也可以分别运行在不同的机器上,在一台机器上运行程序,而在另外一台机器上显示图形界面。

X Window 中的 Server 和 Client 的概念和我们平时接触到的“Server/Client”概念刚好相反。很多熟悉 Internet 原理的人,第一次接触 X Window 的这两个概念都会搞错。比如,我在一台本地机器上运行 Ubuntu 18.10 桌面版,而在另外一台远程机器上运行 CentOS 7(纯字符界面),当我用 ssh 从 Ubuntu 连接到 CentOS 的时候,Ubuntu 是 Client,而 CentOS 是 Server。在 X Window 中,Server 偏偏是我面前的这台 Ubuntu,X Server 运行在 Ubuntu 上。我可以在 CentOS 中运行 GVim,但是窗口显示在 Ubuntu 中,这时,GVim 是一个 Client 程序,它在远程机器上运行,而它的窗口显示在本地。

理解 display 和虚拟控制台##

前面提到网上很多介绍 X Window 的文章都是先让系统进入字符界面,然后手动启动一个 X Server。其实这完全没有必要,因为在同一台机器上完全可以运行多个 X Server,只需要让每个 X Server 的 display 不同即可。那么 display 究竟是什么呢?

在 X Window 中,可以通过hostname:display_number.screen_number来指定一个屏幕。可以这样理解:一台计算机可以有多个 display,一个 display 可以有多个屏幕。所以,display 相当于是计算机配备的一套输入输出设备,一般情况下,一台电脑只配一套键盘鼠标和一个显示器,特殊情况下,可以配多个显示器。

现在问题出来了,我的电脑只有一套键盘鼠标和一个显示器,也就是只有一个 display,那又怎么能运行多个 X Server 呢?那是因为在 Linux 中,还有虚拟控制台这样的高级特性。只需要同时按下 Ctrl+Alt+F1、Ctrl+Alt+F2、...、Ctrl+Alt+F7,就可以在不同的虚拟控制台中进行切换。在 Ubuntu 18.10 中,虚拟控制台 3 到 6 运行的是 agetty,也就是字符界面,虚拟控制台 2 运行的是 Xorg。(Fedora 中不一样,虚拟控制台 1 运行的是图形界面,其它的是字符界面。)如下图:

我们可以直接运行 X Server 程序来启动 X Server。/usr/bin/X 和 Xorg 都是 X Server 程序。其实 /usr/bin/X 是 Xorg 的符号链接,用哪一个都是一样的。

启动 X Server 的时候可以指定 display 参数,因为可以省略掉 hostname 和 screen_number,所以可以用:0,:1这样的格式来指定 display。在我的机器上,本来就有一个 X Server 在运行,display :0 已经被占用了,所以我使用 sudo X vt8 :1 -auth /run/user/1000/gdm/Xauthority -retro 来在 display :1 上再运行一个 X Server,如下图:

其中的 -retro 参数是为了让 X Server 的背景显示为斜纹,否则背景为纯黑色,那就看不出来是否启动了 X Server。vt8 参数指定将新启动的 X Server 放到第 8 个虚拟控制台。:1参数指定新启动的 X Server 的 display number。启动 X Server 后的效果如下图:

按 Ctrl+Alt+F2 回到 display :0,在新启动的 X Server 中运行一个 GVim 看看效果。运行 GVim 时,使用-display :1参数指定窗口显示在新启动的 X Server 上,使用 -geometry参数指定窗口的大小和位置。

再按 Ctrl+Alt+F8 切换到 display :1,看效果。如下:

不知道为什么,在 Ubuntu 18.10 中的虚拟控制台中切换两下,新启动的 X Server 就会崩溃退出。而且切换到虚拟控制台 8 再切换回来,我的 Ubuntu 桌面的分辨率也变成了 800x600,非常不爽。当然,这里的展示只是为了证明能在一台机器上运行两个 X Server,能看到效果就行。

远程连接 X Server##

前面展示的在一个系统中运行两个 Xorg 并不是很吸引人,毕竟新启动的 X Server 太丑了,而且 Xorg 的参数一大堆,不是很容易搞。既然 X Client 和 X Server 可以分布在不同的机器上,那么,如果我们能够把别的系统中的 GUI 程序显示到本地机器中,那才比较过瘾。理论上讲,如果在前面提到的 CentOS 7 中运行gvim -display 192.168.40.135:0命令(这里的 192.168.40.135 是 Ubuntu 18.10 系统的内网 IP),就应该可以把界面显示到 Ubuntu 18.10 桌面上,反之,如果在 Ubuntu 18.10 中运行gvim -display 192.168.40.130:0命令(这里的 192.168.40.130 是 CentOS 7 系统的内网 IP),就可以把界面显示到 CentOS 7 中。

但是,这是行不通的。行不通的原因首先是 Xorg 复杂的认证机制。如果没有认证机制把关,随便就能让别的系统把图形界面甩过来,那桌面上岂不是垃圾窗口满天飞吗?其次,Xorg 在启动时往往会带上-nolisten tcp参数,禁止接受从 TCP/IP 网络上传过来的连接请求。要禁用该选项,往往需要去更改 gdm 的配置文件。

我这里就不折腾这些复杂的认证机制和命令行参数了,我这里来点简单的。最简单的把远程机器上的图形界面带回本地桌面的方式,是使用 SSH 的 X11 Forwarding 功能。该功能用起来非常简单,只需要在使用ssh命令连接远程机器的时候,加上-X或者-Y参数就可以了。如下图,我在 Ubuntu 18.10 中使用ssh -X 192.168.40.130远程连接到 CentOS 7 中,然后再运行gvim命令,该 GVim 窗口就显示在了 Ubuntu 的桌面中。

反之,如果在 CentOS 7 中使用ssh -X 192.168.40.135远程连接到 Ubuntu 18.10 中,在运行gvim命令,就可以把 Ubuntu 中的 GVim 显示到 CentOS 7 的桌面中,如下图:

SSH 的 X11 Forwarding 是一个非常强大的功能。我们甚至可以把 Linux 中的图形界面显示到 Windows 中,只需要在 Windows 中运行一个 X Server 即可。我选择的软件是 XMing,然后使用 PuTTY 连接到 Linux 系统。在 PuTTY 的设置中,开启 X11 Forwarding 功能,如下图:

然后可以把 Linux 桌面中的图形界面带入 Windows 桌面,如下图:

理解 DisplayManager 和 X Window 桌面环境的启动过程##

X Server 的启动方式有两种,一种是通过显示管理器启动,另一种是手动启动。在前面的例子中,我通过直接运行sudo X vt8 :1 -auth /run/user/1000/gdm/Xauthority -retro来启动了一个 X Server,这就是手动启动。手动启动 X Server 的方法还有运行 startx 或者 xinit。手动启动 X Server 的缺点就是启动的 X Server 不好看。而显示管理器启动的不仅有 X Server,还有一大堆的 Client 程序,构成了一个完整的桌面环境,界面当然就漂亮多了。

显示管理器(Display Manager)是什么呢?前面我讲到 display 就是一个电脑配备的一套键盘鼠标和显示器,那么显示管理器就是这一套设备的管理器了。显示管理器可以直接管理这些设备,所以它可以控制 X Server 的运行,由它来启动 X Server 那是再合适不过了。系统启动过程是这样的:内核加载-->init程序运行-->显示管理器运行--> X Server 运行-->显示管理器连接到 X Server,显示登录界面-->用户登录后,登录界面关闭,加载桌面环境。从上面的流程可以看出,显示管理器是 X Server 的父进程,它负责启动 X Server,当 X Server 启动后,它又变成了 X Server 的一个 Client 程序,连接到 X Server 显示欢迎界面和登录界面,最后,显示管理器又是所有桌面环境的父进程,它负责启动桌面环境需要的其它 Client 程序。

在 Ubuntu 的早期版本中,使用 lightdm 取代了传统的 xdm、gdm 等显示管理器。从 Ubuntu 17.10 开始,Ubuntu 放弃了 Unity 桌面而回归 Gnome 3,则显示管理器又变回 gdm 了。

可以使用不同的方法对 X Server 进行配置,前面的例子是直接指定命令行参数。除了指定命令行参数,还可以使用环境变量和配置文件。X Server 的配置文件为一般是 /etc/X11/xorg.conf 或 /etc/X11/xorg.conf.d/ 目录下的 .conf 文件,当然,配置文件也可以放在其它的目录中,具体信息,请参看 man xorg.conf。

如果没有配置文件,X Server 将在启动的时候自动检测硬件,然后生成一个内置的配置。Ubuntu 系统就没有配置文件。不过没关系,如果需要使用配置文件的时候,可以通过 X Server 的 -configure 参数生成一个配置文件,里面包含当前自动检测出的配置。如果需要任何个性化的配置,对该文件进行修改即可。

运行嵌套的 X Server##

我们上面运行的 X Server 都是直接占用了计算机的整个显示器和键盘鼠标,事实上,在现有的图形界面中,还可以以窗口模式运行另外一个 X Server,称为 nested X Server。最常用的 nested X Server 是 Xephyr,在 Ubuntu 中可以通过如下命令安装它:

sudo aptitude install xserver-xephyr

Xephyr 的使用非常简单,可以通过man Xephyr命令查看它的使用手册。如果输入Xephyr :1 -screen 1024x768命令,就可以在现有图形界面中打开一个窗口模式的 X Server,其中-screen参数用来指定 X Server 显示区域的大小。以后再启动 GUI 程序,就可以通过程序的 -display :1 选项让程序运行在这个嵌套的 X Server 中,如下图:

怎么样,是不是很好玩呢?除了好玩,还很有用,比如调试窗口管理器啊、连接远程桌面啊什么的都用得着。当然,我这里只是简单展示一下原来 X Window 还可以这么玩。

总结##

1.在一个 Linux 系统中存在多个虚拟控制台,所以可以启动多个 X Server;

2.启动 X Server 的方式有两种,一种是使用 /usr/bin/X、startx、xinit 手动启动,一种是通过显示管理器启动;

3.远程计算机连接本地的 X Server,需要 X Server 开放 TCP 端口,还要搞定安全认证;

4.如果觉得搞定 X Server 的 TCP 端口和安全认证太麻烦,可以使用 SSH 的 X11 Forwarding 功能,远程连接 X Server 超级方便;

5.X Server 的配置,可以通过命令行参数,可以通过环境变量,还可以通过配置文件;

6.可以在现有的图形界面下以窗口模式运行嵌套的 X Server,常用的软件是 Xephyr;

7.使用 XMing 和 PuTTY,把 Linux 图形界面带入 Windows 不是梦。

版权申明##

该随笔由京山游侠在2018年11月01日发布于博客园,引用请注明出处,转载或出版请联系博主。QQ邮箱:1841079@qq.com

Linux 桌面玩家指南:09. X Window 的奥秘的更多相关文章

  1. Linux 桌面玩家指南:18. 使用 Docker 隔离自己的开发环境和部署环境

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  2. Linux 桌面玩家指南:17. 在 Ubuntu 中使用 deepin-wine,解决一些依赖 Windows 的痛点问题

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  3. Linux 桌面玩家指南:16. 使用 CUDA 发挥显卡的计算性能

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  4. Linux 桌面玩家指南:15. 深度学习可以这样玩

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  5. Linux 桌面玩家指南:14. 数值计算和符号计算

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  6. Linux 桌面玩家指南:13. 使用 Git 及其和 Eclipse 的集成

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  7. Linux 桌面玩家指南:12. 优秀的文本化编辑思想大碰撞(Markdown、LaTeX、MathJax)

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  8. Linux 桌面玩家指南:11. 在同一个硬盘上安装多个 Linux 发行版以及为 Linux 安装 Nvidia 显卡驱动

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  9. Linux 桌面玩家指南:10. 没有 GUI 的时候应该怎么玩

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

随机推荐

  1. SVG的动态之美-搜狗地铁图重构散记

    搜狗地图发布了新版的移动端地铁图,改版初衷是为了用户交互体验的提升以及性能的改善.原版地铁图被用户吐槽最多的是pinch缩放不流畅.无过渡动画.拖拽边界不合理等等,大体上都是交互体验上的问题.实际上原 ...

  2. Healwire Online Pharmacy 3.0 Cross Site Request Forgery / Cross Site Scripting

    Healwire Online Pharmacy version 3.0 suffers from cross site request forgery and cross site scriptin ...

  3. ssh框架整合笔记

    1.建立普通的Javaweb项目,导入项目所必须的jar包. 2.配置web.xml文件. web.xml  3.在src下建立struts.xml. struts.xm 4.在实体包下配置  实体名 ...

  4. 如何删除git远程仓库项目的所有内容,重新提交所有内容

    如果我们上传了一个项目到git并已经commit和push了所有内容,但是忘记搞gitignore文件, 导致一些不想加入版本控制的文件,如IDE配置文件,编译文件,部署文件等, 现在不知道怎么办了? ...

  5. eShopOnContainers 知多少[10]:部署到 K8S | AKS

    1. 引言 断断续续,感觉这个系列又要半途而废了.趁着假期,赶紧再更一篇,介绍下如何将eShopOnContainers部署到K8S上,进而实现大家常说的微服务上云. 2. 先了解下 Helm 读过我 ...

  6. linux服务器 jboss-7安装

    jBoss简介 JBoss是一个运行EJB的J2EE应用服务器.它是开放源代码的项目,遵循最新的J2EE规范.从JBoss项目开始至今,它已经从一个EJB容器发展成为一个基于的J2EE的一个web 操 ...

  7. 虚拟机设置静态IP配置

    网关 虚拟机的ip设置  vi /etc/sysconfig/network-scripts/ifcfg-eth0 重启网卡 service network restart 测试 ping www.b ...

  8. 阿里云ECS安装Cadvisor报错

    阿里云ECS安装Cadvisor报错安装命令: sudo docker run \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:ro \ -- ...

  9. TensorFlow从1到2(六)结构化数据预处理和心脏病预测

    结构化数据的预处理 前面所展示的一些示例已经很让人兴奋.但从总体看,数据类型还是比较单一的,比如图片,比如文本. 这个单一并非指数据的类型单一,而是指数据组成的每一部分,在模型中对于结果预测的影响基本 ...

  10. 【Python3爬虫】用Python中的队列来写爬虫

    一.写在前面 当你看着你的博客的阅读量慢慢增加的时候,内心不禁有了些小激动,但是不得不吐槽一下--博客园并不会显示你的博客的总阅读量是多少.而这一篇博客就将教你怎么利用队列这种结构来编写爬虫,最终获取 ...