2012年6月22日星期五

10 个痛恨 Linux 的理由

  1. 首当其冲的还是内核问题。
    还记得当年 Linus Torvalds 和 Minix 的作者的那次争论么?或许是为了图省事,Linux 被做成了宏内核。导致了内核过于臃肿。即使是性能提升了,也导致了很多问题。
    1. 内核模块是和内核绑定的。这导致了很恶心的现象,每一次发布内核都需要发布内核模块,而每一次编译内核都要花掉 2/3 的时间在上面。
      你会说,我用发行版提供的内核包,不用自己编译。那问题是,截止 3.4.3 版本,Linux 内核(包括内核模块的二进制包)的大小已经达到了 56.75MiB,至少给网速慢的用户带来了升级上的负担。
      如果,你另外安装了什么驱动(比如 Nvidia 的闭源驱动),每一次更新内核都需要重新编译。你会忘记吗?你应该有过这样的经历。
    2. 内核过于臃肿带来了第二个问题。如果一个驱动崩掉了,整个系统估计也就 Kernel Panic 了。幸好现在的 Linux 提供了一些保护机制,让你至少还可能接着用一段时间,保存手头的工作。
      而我遇到的问题更麻烦,那是在 BtrFS 不太稳定的一段时间里。每当 BtrFS 崩溃,系统就会自动跳回 console,然后提示 btrfs-**** 进程崩溃,给出 backtrace。这时候内核还是在运行的状态,用 Magic SysRq 还能完美重启。而有一次直接 Kernel Panic 了,在 Xorg 下连提示都没有给我,就直接死了,Magic SysRq 都不能用。
  2. 系统调用的命名问题,这是一个历史问题。
    你可以觉得当年 Unix 的 creat() 函数名字很恶心,因为Unix 的创始人认为当年用的电脑键盘使用起来非常费劲,所以宁可省去一个字母(天哪,省别的字母多好,省去这一个字母有什么用?)。但是 POSIX 为什么不说“creat() is deprecated, use create() instead”呢,至少这不会造成小学生的英语水平下降呀。
    如果这个你还能接受的话,那就见识一下 dup() dup2() dup3() 三兄弟吧。你知道它们是干什么的呢,参数怎么用呢?什么?你说还有 man 手册来查?我告诉你,Windows 里面的 MSDN 手册比 Linux 里面的 man 好用多了,而且支持现代化的超链接。
    以前看到一个 Windows 的批评者说 Windows 里面的 CreateWindowEx() 函数参数太多,难以记忆。那我只好用两个观点来反驳了——Linux 里面的 dup*() 家族就不麻烦了?并且哪个人在写 Windows 软件的时候不用 MSDN 做参考(或者参数补全功能)?
    因此,我还是偏好于 Windows 的 API 命名风格(Windows 值得欣赏的估计也只有 API 了),那么 creat() dup() dup2() dup3() 就会叫做 CreateFile() DuplicateHandle() DuplicateHandleTo() DuplicateHandleToEx() 了(而事实上 Windows 本身的 CreateFile() 和 DuplicateHandle() 都实现了 creat() dup3() 的功能,将一些参数填成零也就实现了 dup() 和 dup2() 的功能)
    (引用 @红繁君 的一句话:谁能记住 mktemp mkstemp mkstemps tmpnam tempnam tmpfile 的区别,请举手。)
  3. Linux 前端缺乏创新意识,这也是 Linux 始终无法打入桌面领域的原因。
    这些年 Linux 在桌面市场也在不断发展,但是永远无法撼动 Windows 霸主的地位。不是说 Windows 完美无暇,而是说 Linux 永远跟着别人的脚步在走。
    比如 Gnome 推出了 Gnome-shell,结果遭来了一大堆骂声。批评者说,“难道 Linux 的桌面版以后都要向手机界面迈进?”我只想反问,Linux 社区的激进的极客精神哪里去了?毕竟我也比较喜欢 Gnome-shell,除了一些很小的问题之外还是非常优秀的桌面环境(我也不否认 KDE 和 LXDE 等)。
  4. Linux 的 Kernel Panic 处理很恶心。
    如果你正在图形环境下工作,这是不幸地发生了 Kernel Panic,会有什么现象呢?
    根据内核版本和 X Server 版本的不同,可能你会被拖回 console,然后面对黑底白字和满眼的 backtrace,弄得你手足无措。而也有的就直接死掉了,连提示都没有!(除非你当时在 Virtual Terminal 下,还能看到 backtrace)
    如果是 OS X 或者是 Windows 发生了内核崩溃,不仅会提示你发生了错误,还会把 memory dump 存在硬盘里,这比简简单单地把 backtrace 打在屏幕上要好得多吧。况且如果 backtrace 超过了 24 行,那 backtrace 有什么用!
    据说 Windows 8 开始要改善系统蓝屏的用户体验,不仅是蓝屏的背景颜色有所改变,而且提示文字支持了中文。Linux 什么时候能做到呢?
  5. Linux 对用户不完全友好,对开发者友好。
    虽然人们曾经的“Linux 不用户友好”的概念已经被有些发行版推翻(比如大名鼎鼎的 Ubuntu),但是做的还不够。(不过也难说 Windows 能友好到什么程度,OS X 那才是真正地注重“用户体验”)
    用户体验不是华丽的特效,也不是提供厚厚的操作手册;而是用户永远能在他认为该出现的地方找到他要的功能
    Ubuntu 虽然提供了软件中心(就这还是照苹果抄来的),但是没有提供自动清理软件包缓存的功能,导致缓存吃硬盘空间。当然,Windows 也有不清理 Temp 文件夹的坏习惯,但这不是 Ubuntu 不清理缓存的借口。而相反,ArchLinux 不清理缓存则是注重用户体验。(如果你用过 ArchLinux,你就知道这话的道理了)
    而至于对开发者伪友好,举一个例子就可以说明了。Linux 虽然提供了大量的开发工具,但是从来没有一个得心应手的 IDE,如果说 Linux 的开发者不喜欢 IDE 的话,那么考虑对于一个新手来说 IDE 是不是很重要。一个刚刚从别的平台迁过来的开发者,如果没有 IDE,会很不适应,然后被轻易吓跑。
  6. 图形工具包的不统一。
    这可以追溯到当年 GTK+ 和 QT 闹对抗的时代。然而有的人却找借口说,X 当年的设计就是这样的,“提供机制,而不是策略”,所以让别人自己设计图形工具包。这个说法并没有错,但造成了很多不便。开发者纠结该用什么库,是 GTK+ 还是 QT,还是 TK、FLTK、wxWidget,还是干脆只用 X。而对于用户 ,不仅需要安装一大堆的库,而且要忍受不同库之间的界面样式、主题不同之苦。开发者如果想调用用户的文件浏览器来显示某个目录的内容,就要枚举 Nautilus、Dolphin、PCMan……虽然 freedesktop 缓解了一些问题,但是没有真正解决。
    同样的问题也发生在 ALSA 和 OSS 之间,但我认为这是好事,因为促成了竞争(前提是 ALSA-OSS 兼容包的存在)。
  7. 进程通信的支持问题。
    曾经有一个人说,Linux 里面有万能的管道,Linux 所有的进程通信只需要管道就够了。
    现在,dbus 的出现说明了这种论断是错误的。首先,管道只有单向性,只能去不能回。并且,管道只能传输文本流,对于别的类型,转换的时候既会丢失精度,也降低了效率。当然我不是完全否定管道的,因为即使管道的一端换成了同样功能的软件也能照样运行。(用 less 来替换 more 就是一个很好的例子)
  8. 人们明知道内核过于臃肿不是好事,却仍在变本加厉。
    KMS 是最好的例子。上次听说某显卡驱动为了增强性能以及与内核的集成性,由 UMS 改为了 KMS。与其将更多的东西往内核里塞,不如从内核里拿出东西出来。
    本身内核就应该提供一些对于用户态驱动的接口,让驱动除了使用 int $0x80 以及直接在编译时和内核连接之外有别的、更好的选择。
  9. 对未来的考虑欠缺
    你应该知道 /dev/?d* 表示硬盘,比如 /dev/sda1 表示第一块(SATA 接口)硬盘。那么问题是,如果你安装了 27 块硬盘,该怎么编号呢?Red Hat 的解决办法和 Microsoft Excel 对于第 26 列之后的编号一样:sda sdb sdc ... sdz sdaa sdab ... sdaz sdba ...
    那么带来的问题是,如果原来有一个 Bash 脚本,枚举每一个磁盘,可以用
    for i in /dev/sd? ,现在只可以用
    for i in $(ls -1 /dev/sd* | tr -d [:digit:] | sort -u)
    了(如果有人想到了更简洁的方法请告诉我)
    当年 /dev/pts1 改成 /dev/pts/1 就是因为考虑得不够长远(改过之后也带来了不同发行版和类 Unix 系统分支之间的不兼容性),Intel 也犯过这样的错误,MBR 的设计者也是,甚至 IPv4 的制定者,甚至是“千年虫”也是因为这个导致的。Linux 现在为什么不可以汲取这样的教训呢?比如 Hurd 使用 /dev/hd0s1 的表示,用数字,枚举起来很方便,特别是在 Bash 脚本中。
  10. Hurd 才是 GNU 的未来。
    GNU/Hurd 在 Linux 开始之前就已经动工了,现在 Linux 都更新到 3.x 版本了,Hurd 连一个正式版本都没有释出,这也难怪 Hurd 没有成为开源社区的主流。
    但是的确如此,Hurd 才是 GNU 的未来,Mach 微内核的优雅设计,GNU 自身的支持,更好的安全性能,等等……
    但是毕竟 Hurd 还没有正式做出来,所以这只是痛恨 Linux 的理由,而不是不用 Linux 的理由。
总结:无论如何痛恨 Linux 这个操作系统,都是希望让它做得更好。并且鉴于目前在开源社区里没有更好的替代品(难道有大多数人在家里用 BSD 或者是 Minix 作日常使用么),我们也只能继续使用 Linux,并且向开源社区提供力所能及的帮助。