xl-2019-wsl2-1.jpg


引言

我使用 Linux 已经有很多年了,最开始接触 Linux 的时候是从 RedHat 9(没有 Enterprise),中途换过 N 个不同的发行版。多年前,我在 BlogJava 上面分享 Java 经验的时候,也偶尔提一提 Linux,如怎么在 Linux 系统上面安装 JDK、Tomcat、Bugzilla 等内容,也写了一些自己选择 Linux 发行版的体会。
 
但是后来我发现,我的体会有一些是错误的,比如我因为字体的原因喜欢中科红旗 Linux,而对 RedHat Enterprise Linux 有一些不公正的评价。于是,我整理 BlogJava 上的博客时,将一些和 Linux 有关的我认为内容有错误的随笔删除了。这次删除直接导致我在 BlogJava 上的排名从 30 几名下降到 50 几名,又经过一年多的经营,现在也只是勉强进入 50 名之内。

完全使用 Linux 作为自己的工作环境有很多困难,被 Linux 折磨久了我就有了一些自己的方法。使用这些方法来解决 Linux 中碰到的问题可以说是屡试不爽。因此,从去年 4 月底我完成硕士论文答辩后,就开始将自己折腾 Linux 的心得整理成文,到目前,正好历时一年。所以,我在这里对这一系列随笔做一下整理。

使用 Linux 的一些困难和解决方法

完全使用 Linux 进行工作和娱乐是非常困难的。所以有很多 Linux 反对阵营的人就直接说,你们那些所谓的 Linux 用户,也不过是把它当成玩具而已,玩一玩再删掉,有什么意义呢?这真的是一个问题,对于普通用户来说,使用 Linux 的难度还是太大了,即使有很先进的图形界面(如Gnome、KDE)也不行。
 
就算是程序猿们,使用 Linux 也要经过很多波折,而且需要很大的耐心,才能最终把 Linux 从玩具变成神器。大家没有把 Linux 当成日常使用的工具,并不是 Linux 系统或者 Linux 系统下的软件不能够胜任我们的工作,而是被使用 Linux 的困难吓倒了。

举例说明,由于 Linux 是一个很“优秀”的多任务多用户操作系统,“优秀”就意味着严格,在 Linux 系统中由于用户权限的限制,有些事情干起来就不是那么方便。所以,使用 Linux 系统的第一步就是要了解 Linux 系统的用户管理方面的知识。第二步需要了解的是 Linux 的文件管理,虽然没有像 Windows 中的 C 盘 D 盘这样的盘符概念,但是文件和目录以树形组织起来还是比较容易理解的,难就难在 Linux 系统中,每一个文件或目录都有其所属的用户、用户组,并且具有不同的权限位,所以要学习 Linux 系统还要学习它的文件管理。第三步要了解的就是 Linux 系统的任务管理,怎么运行一个程序,怎么让程序在后台执行,怎么向一个程序发送信号等等。可以这么说,Linux 绝对是一个面向专家的系统,对普通用户,它有着天然的壁垒,图形界面做得再好,也无法跨越普通用户和专家之间的鸿沟。

再来说说图形界面。Linux 有非常多的桌面环境可以使用,如 Gnome、KDE、Xface 等等,但是这些桌面环境也不是完全没有问题。什么界面不好看、字体不美观、没有相应的显卡驱动等等问题不一而足。而且这些桌面系统也并不是永远那么稳定,极有可能哪天你安装一个软件包或者卸载一个软件包后,图形界面就进不去了,如果你不会在字符界面下配置网络,无法重新修复相应的软件包,就只剩下重装系统这一条路了。

即使有问题,我们也要征服它。我在刚使用 Linux 的时候,碰到问题总是不知道到哪里找答案,有些东西书上没有,网络上也难以查到,查到的信息有时候也很过时。还有时候,我按照书上或网络上的方法下载安装一个软件包,却不知道这个软件包的文件都放到文件系统的哪个地方了,程序在哪里、文档在哪里、配置文件又在哪里呢?经过多年的使用,我总结了《玩转Linux系统的方法论》,按照这些方法论,Linux 中的问题基本上都可以迎刃而解。

下一个问题,就是 Linux 下的默认图形界面不够美观。如果一个系统看起来不顺眼,估计大家是没有心情继续用下去的。Fedora 默认主题就很丑,Ubuntu 倒是做得不错。我拿到 Fedora 系统后,第一件事就是换主题、换背景。Linux 系统下的字体配置也很成问题,新安装的系统上网、办公都很不舒服。因此,我总结了《Linux桌面系统字体配置要略》、《在Ubuntu 14.10中借用Windows的字体》、《桌面美化那点事儿》,一步一步将 Linux 打造成自己顺手顺眼的工作环境。有时候,我们还要切换到字符界面进行工作,所以我总结了《全网络最正确的让Linux开机进入字符界面的方法及设置FrameBuffer分辨率的方法》,这也是属于让 Linux 看起来更顺眼更舒服的范畴。

Linux 系统的图形界面是基于 X Window 的,所以对 X Window 也要有一定的了解。我又花时间探讨了《X Window的奥秘》。为了防止图形系统被玩坏了无法恢复,我研究了《我该如何备份系统》,不过在实际应用中,因为我总是不断更新系统,所以我只备份了我的一些配置文件和工作文件。然后,对于安装显卡驱动,我也有自己的总结《Fedora 21安装Nvidia驱动以及失败后的补救方法》。

在 Linux 系统下工作,需要一个好的输入法和编辑器吧。我在 Fedora 中使用 Intelligent PinYin 输入法,这个输入法已经很不错了,在 Ubuntu 中有更好用的搜狗输入法,当然不能错过,请看这里《在Ubuntu 14中使用搜狗拼音输入法》。然后,对于文本编辑器,我选择 Vim。Vim 要配到让自己顺手才行,所以有了这篇《打造属于自己的Vim》。

然后就是编程了,C 语言是 Linux 系统的母语,所以完善的 C 语言编程环境自然是必不可少。由于 C 语言相当简单,很多时候使用 Vim 就足够了,于是就有了《感悟GNU C以及将Vim打造成C/C++的半自动化IDE》。有一段时间,我非常热衷于编写自己的操作系统内核,自制操作系统需要从 16 位的实模式写起,然后再让 CPU 进入保护模式。几乎所有的书和网络教程一提到 16 位实模式代码,都使用 NASM 编译器。我偏偏喜欢 GCC,为了不使用 NASM,我有了这一篇《使用GCC和GNU Binutils编写能在x86实模式运行的16位代码》。这也进一步说明,使用 C 语言编程,除了 GCC,Binutils 也是一个很重要的工具包。除此之外,Gnu autotools 也是很重要的工具包,我在这一篇《使用Eclipse和Gnu Autotools管理C/C++项目》中进行了展示。

除了 C 语言,脚本语言在 Linux 中的地位也很重要。这一篇《Bash脚本编程语言中的美学与哲学》总结了我对 Bash 语言的领悟。另外,从我的随笔分类中可以看出,我有时是需要写一些和数学、数值计算有关的东西的,要写这些东西,必须要有适当的工具,关于工具的内容我后面再总结,但是这一篇《适合数值计算的语言需要具备什么样的特色》,要归纳到我对编程语言的理解这个类别中。

然后就是和写文章、发博客、绘图、数学公式有关的一些工具了。它们是《优秀的文本化编辑思想大碰撞(Markdown、LaTeX、MathJax)》、《再来说说LaTeX》、《数值计算和符号计算》,以及前面提到的《适合数值计算的语言需要具备什么样的特色》。当然,还有画图工具《发博客必备的五大图片处理神器》。

最后,目前的虚拟化技术如火如荼,再加上我折腾 Linux 系统有时也需要用到虚拟机,所以对 Linux 系统下的几个主流虚拟机进行了探讨。它们是《虚拟机体验之QEMU篇》、《虚拟机体验之KVM篇》、《虚拟机体验之VirtualBox篇——性能强大的经典架构》、《虚拟机体验之Xen篇——令人脑洞大开的奇异架构》。有时不想用虚拟机,就想办法把不同的 Linux 发行版安装到一台电脑上,像这样《在同一个硬盘上安装多个Linux发行版及Fedora 21初体验》。

我眼中的 Linux 哲学总纲

《Unix 编程艺术》这本书中,对 Unix 编程哲学的总纲总结为“K.I.S.S”,即Keep it simple, stupid。对这个说法,我深深地不以为然。当然,你可以认为这是 Unix 环境编程的哲学,而不是类 Unix 系统本身的哲学。事实上,一个系统中的程序如何设计,往往也影响到这个系统如何使用。例如,Linux 系统中的程序设计时往往只让自己做到最少的功能,并通过管道和其它程序配合使用,从编程的哲学来讲,这就叫只做一件事并做好,从用户的角度来讲,他就需要学习很多小工具,并将这些工具配合起来使用。正是由于将各种工具搭配使用可以有各种各样的组合方式,充满了创造性,所以,也就充满了乐趣。另外,每一个小工具都是做得那么精湛,因此它们的生命期会很长,从用户的角度来讲,就是学会一项技能以后,很长一段时间不会过时。另外一个例子就是 Linux 程序设计时的最小立异原则,它们几乎遵循同样的命令行参数、配置文件语法、正则表达式语法等等,从用户的角度来看,这个系统就会显得很整齐划一,有时候不用看文档,猜都能猜到某些工具怎么使用。

既然我不赞同 Linux 的哲学是“K.I.S.S”,那么我的答案是什么呢?我认为,Linux 哲学的总体纲领是“交流和共享”。这要从 Unix 和 Linux 以及和 Gnu 的历史说起。Unix 刚诞生的时候,是不允许当作商业产品出售的,为了交流,Unix 系统的源码是完全公开的,很多人都向 AT&T 实验室索要 Unix 的源码。那时候,Ken 伯伯是一包一包的磁盘往外寄,但是他毫无怨言,还在每一个包裹里附上一张纸条,上写“爱你的Ken”。交流和共享的回报就是全世界那么多的聪明人为 Unix 系统添砖加瓦,然后 Unix 系统飞速发展。
 
至于 Unix 版本的分裂和最后标准的形成这样的过程我就不写了。再来说 Linux,其内核诞生之初便放到网络上和大家交流,然后借助网络协作飞速发展。Gnu 就更加不用说了,那是开源界的鼻祖,交流和共享是它的立身之本。我觉得“K.I.S.S”这个原则应该是有点过时了,如果按人年计算,Linux 的工作量已超过几千万人年,它一点也不 Simple,一点也不 Stupid。相反,它还有那么一点 Complex,而且还很 Brilliant,它的复杂会把某些人拒之门外,它闪光的思想又会把另外一些人紧紧吸引。(这里不仅是指 Linux 内核,而是指整个 Linux 系统,包括其中的各种软件。)

其它的哲学应该都是从“交流和共享”这个总纲延伸而来的。其中一个结果就是在 Linux 系统下有着海量的软件、编程工具可以使用。因为每个人都可以向 Linux 贡献自己的东西嘛。而且 Linux 也是非常鼓励大家开发自己行业领域的专业软件,鼓励大家设计适用于各种场景的专用编程语言。所以使用 Linux,你一定会有一种感觉,那就是一座大大的宝藏就放在自己眼前,入宝山怎么可能空手而归呢?另外一个结果就是在 Linux 系统中展现了很多非常闪光的思想,因为交流,那些不好的东西慢慢就被淘汰了,留下的,自然就是精粹。

我这一系列随笔中展现出的 Linux 哲学

在我的这一个系列中,首先揭示的 Linux 哲学就是它的透明性和可用性。《Linux 就是这个范儿》这本书里面说 Linux 有四大笨,分别是:万般皆文本,随处用脚本,规律无处寻,配置乱生根。我认为,这“四大笨”正是 Linux 透明性的体现,但是要改一个字,不是“规律无处寻”,而是“规律有处寻”。下面我来一一论证。

首先来说万般皆文本。在 Linux 系统中,不管是保存数据还是程序之间通讯,首选纯文本格式。一提到纯文本格式,大家首先想到的困难会有两点,其一是占用的存储空间比较大,其二是文本的解析比较困难。但是和二进制的存储格式相比,纯文本最大的优点就是适合人类阅读。在 Linux 系统中,很多程序都是基于行来解析文本文件的,甚至包括那些版本控制工具,它们也是基于行的比较来体现代码的变化。富文本格式往往也倾向于使用纯文本的方式来进行编辑和保存,只是需要在进行显示或打印的时候,再通过特定的工具转化成多媒体格式。在我的这一系列随笔中,这两篇《优秀的文本化编辑思想大碰撞(Markdown、LaTeX、MathJax)》、《再来说说LaTeX》可以说是对这一个哲学进行了阐释。
 
另外,进程间通讯也是纯文本占优势,因为那些专用的基于二进制的协议实在是太不透明了,开发和调试都很困难,也不是很健壮。以前在 Windows 下编程时,COM 和 DCOM 都研究过,写 Java 的时候,也在 RMI 方面下过功夫,现在,仍然有很多编程语言在搞对象的序列化和反序列化,这些都是基于二进制的,不透明。后来逐渐接触到 JSON、XML,以及面向服务编程是用到的 SOAP 协议,才深深体会到纯文本格式的优美。其实目前网络上的用户层通讯协议,比如 HTTP 协议之类的,都是基于文本行的。

其次来说说随处用脚本。关于脚本编程我这里不多讲,这里只说脚本带来的好处。脚本的坏处大家也可以马上想到,那就是运行速度确实不怎么样。但是脚本的好处是显而易见的,那就是逻辑清晰、便于阅读。脚本就是一个纯文本,随便找个编辑器打开就可以阅读,如果有超级用户权限也可以随意修改。在我的这个系列中,《Bash脚本编程语言中的美学与哲学》总结了我对 Bash 语言的领悟。而且有很多时候,我是通过阅读脚本来理解问题和解决问题的,如这一篇《全网络最正确的让Linux开机进入字符界面的方法及设置FrameBuffer分辨率的方法》,通过阅读 lightdm 的启动脚本来找出让 Ubuntu 进入字符界面的方法,还有这一篇《探索Linux系统的启动过程》,通过阅读 lsinitrd 脚本来找到解包 initramfs 文件的方法。

然后来看规律有处寻。对于 Linux 新手来说,有时确实有点摸不着头脑,感觉似乎找不到任何规律。事实上,Linux 下的软件的文档是非常完善的。几乎每一个程序都有相应的手册页,使用man命令就可以阅读,如果是 Gnu 出品的,可能还有info文档。另外,几乎每一个程序都可以带--help选项。例如在《Fedora 21安装Nvidia驱动以及失败后的补救方法》这一篇中,我通过带--help选项运行从 NVIDIA 官网下载的安装文件,就得到了怎么把该安装文件解包的方法。除了手册页,还有很多软件提供的文档是 PDF 格式的,也有办法把它们找出来,如《再来说说LaTeX》这一篇和《虚拟机体验之VirtualBox篇——性能强大的经典架构》这一篇,找出文档后,软件的使用就不再是无规律可循了。

最后来分析配置乱生根的问题。配置文件、环境变量、命令行参数是我们定制软件行为的三驾马车。Linux 中有一个很讨厌的哲学——提供机制而不是策略,为什么说它讨厌呢,我后面再讲。在 Linux 中,一个软件可以有很多选项,可以表现出各种各样的行为,这些都要靠配置文件、环境变量、命令行参数进行定制。配置文件本身是纯文本格式的,阅读和修改都不是问题,其透明性是很好的,主要问题是“乱生根”,有时候根本不知道配置文件放在什么地方、文件名叫什么。这个问题也不是没办法解决,使用《玩转Linux系统的方法论》中介绍的方法,很容易找到某个软件包的配置文件都放在什么地方。

其实和透明性相关的还有一个硬货,那就是源代码。Linux 可以说是开源软件的代表,内核及其系统下的软件都是开源的,源代码可以随意获得和阅读。但是能随意阅读源代码就说明透明性一定好吗?那不见得,因为源代码太复杂了,就算让你随便读也不一定读得懂。所以我碰到问题后,首先考虑的是读文档,而不是读代码。Linux 内核的源码目录我也是经常逛,但是主要还是以读文档居多,基本没读代码,最多也就是看了那基本经典的专著之后进代码瞅一眼,验证验证而已。有时候源代码也可以提供一些参考,比如 OpenGL 编程,不知道它和 X Window 如何交互的话,看一看 freeglut 的代码还是很有收获的。在《玩转Linux系统的方法论》这一篇中,我有介绍获取源码包的方法。

我这一个系列的随笔可以说是用最好的方式展现了 Linux 的透明性。掌握了我这一系列博客中提到的方法,在 Linux 系统中碰到任何困难,都可以找到解决方法。换一种说法,其实 Linux 系统本来对用户就是非常透明的,一点都没有遮遮掩掩,如果你用不好 Linux,那是因为你水平还不够,而我的这一系列随笔就是教大家怎样去看穿它。

说完透明性再来说说可用性。通过前面的阐释可以看出 Linux 系统是非常透明的,所有困难都可以克服。另外一个问题就是 Linux 真的可以满足我们日常工作、娱乐的所有要求吗?也就是说,Linux 真的具有可用性吗?我觉得我的这一系列随笔就是对这个问题最好的回答。在这一系列随笔中,我展示了在 Linux 桌面环境中,我的日常工作是没有问题的,不管是编程、画图还是做数学工作,很多软件都非常优秀,功能强大、运行稳定且界面美观。在我没有展示的领域,如写论文、做幻灯也是没有问题的,LibreOffice 很强大,和 MS Office 一样好用,上淘宝、登网银也没有问题,因为它们的插件都支持 Linux 系统下的 Firefox 浏览器。如果不要图形界面,其在服务器领域占有的市场比例更是遥遥领先,这个可用性就不需要我来废话了,大家心知肚明。

在我的这一系列随笔中,有几篇还展示了 Linux 中某些软件前后端分离的策略以及其带来的优势。使用 Linux 系统有两种方式,那就是 CLI 和 GUI。你即可以选择字符界面,也可以选择图形界面,它们各有优势。字符界面通过输入命令来执行程序,通过脚本和管道让许多工具配合工作,如果用得好,可以获得非常高的效率。而且字符界面的程序非常适合进行脚本化和自动化,如开机启动某任务、定时启动某任务等等。图形界面的优势呢?就是使用起来非常方便,有丰富的菜单提示,用鼠标点点画画就可以完成工作,但是要完成批量任务或定时任务就不是那么方便了。也不是没有解决办法,MS Office 提供的宏就是一种解决办法,Photoshop 也可以录制动作生成 Action 然后回放。这说明不管是在 Linux 环境还是在非 Linux 环境,用户对自动化的需求都是一样的。

有些工作非使用图形界面不可,比如画图和在虚拟机中运行具有图形界面的客户机;有另外一些工作则把图形界面当成累赘,比如在没有图形界面的服务器中使用虚拟机,并且要有开机自动启动、定时启动、远程管理、批量化管理这些功能。要解决这个冲突,Linux 中广泛采用的是前后端分离的策略。在《数值计算和符号计算》中,我介绍的 Octave、Maxima 等软件,就都有在其命令行的版本上,加上了一个 GUI 封装的图形化版本。还有《虚拟机体验之VirtualBox篇——性能强大的经典架构》中介绍的 VirtualBox 虚拟机,就是一个经典的前后端分离架构,VirtualBox 的图形界面就是对其命令行工具的 GUI 封装。

Linux 之得和 Linux 之失

Linux 还有一个很讨厌的哲学,那就是提供机制而不提供策略,而且这个策略还被很多人追捧,对于这一点,我是持反对意见的。提供机制而不提供策略的几个典型例子,一是系统启动时的初始化,Linux 只决定内核初始化完成后将控制权交给/init程序,至于/init程序怎么启动其它的服务、怎么进入系统,就看各个发行版各显神通了。二是 X Window 图形界面的实现,只提供机制,不提供策略,在不同的发行版中,可以使用不同的窗口管理器,编程也可以使用不同的图形工具包。

那么这是优点还是缺点呢?不好说。支持者认为这是优点,因为可以随时更换策略,所以这些机制的生命期特别的长。就拿 X Window 来说,已经有 30 多年的历史了,但是依然没有被淘汰,每次只要换个窗口管理器,又可以生龙活虎好多年。支持者的另外一个观点就是只提供机制而不提供策略,可以给用户提供更加丰富的定制空间,正如 X Window,可供用户选择的桌面环境就有 Gnome、KDE、XFace、Enlightment 等等一大堆,还有 Ubuntu,硬是在 Gnome 的基础上再次开发,写出了一个 Unity 桌面。

我认为,它的缺点也很明显。其中一个缺点就是这个策略明显地造成了 Linux 发行版的分化。现在的 Linux 发行版太多了,每一个都搞一套自己的启动机制,每一个都搞一个自己的软件包管理机制,每一个都说自己的策略怎么好怎么好,最终,想选择 Linux 的用户被逼成了选择障碍综合征,不知道怎么选,只好抛弃 Linux。即使是同一个厂家或同一个社区的发行版,也分成不同的桌面定制版,而且有时候,有些软件专为某种桌面定制,在其它的桌面环境中运行效果就很差或者很不稳定,这造成了 Linux 用户的分裂,同时也造成了 Linux 新手学习上的困难,因为技能树的分支太多了,不知道怎么攀。

版本分化还不是 Linux 占领市场最大的问题。最大的问题还是出在提供机制而不是提供策略上,因为当 Linux 允许用户自己指定策略的时候,往往也意味着用户必须得自己指定策略。Linux 系统的发行者没有为大家提供一个可以让大部分人都满意的预先定制好的策略,相反,而是只提供基本可用的系统。几个比较明显的例子,我装完系统后,首先要做的事就是重新配置字体、选择系统主题,对于常用的工具如 Vim 之类的,还要自己修改它的配置文件。最终的结果,就是刚接触 Linux 的用户,如果不是专家或者特别有耐心,很快就知难而退,放弃了。

曾经有一段时间,字体的配置方法也是很分化的,使用不同的图形界面包(如QT、GTK)编写的软件,使用的字体配置方法都不一样,所以要改系统的字体,得改好几个地方的配置文件。这个问题也导致如果一个为 KDE 编写的程序如果运行在 Gnome 桌面上,界面往往会比较丑陋,反之亦然。幸好,正如我在某一篇随笔里说的,字体配置方法被 FontConfig 统一了,这为我们最终用户省了很多事。也证明,Linux 中的提供机制而不是策略的哲学带来的 Linux 的分化还是很有弊端的。还是合而为一比较方便,而且最终也是分久必合,如 init 系统即将被 systemd 统一。

总结

这一篇随笔只是对我这一年中所写的 Linux 应用环境实战系列随笔的一个总结,顺便阐释了一下从我的随笔中能够看出来的 Linux 的透明性、可用性。这一系列随笔没有多少编程方面的东西,主要展示的是方法论和工具论。最后,如果你早就被 Linux 深深吸引住了,但是又无法说出吸引你的究竟是什么,那么我推荐你读一下《Unix 编程艺术》,这本书虽然很老了,但是读完之后确实是会有巨大的收获。
 
 

作者:京山游侠