Linux避坑指南

在运行了一个多月后,我终于把VirtualBox上的Xubuntu之车开到沟里去了。事情的起因是原有的VDI硬盘被写满(12 GB),在使用vboxmanage modifymedium disk bioinformatics.vdi --resize 32768 命令扩容后,出现输入正确的密码后,无法登录(闪退)的问题。通过root用户名登录进系统后,发现sudo用户home文件夹下很多文件和子文件夹的所有者变成了root(从而无法在启动时被其他用户访问)。运行ldconfig命令并删除了其他用户的.Xauthority文件后,其他用户可以登录,却发现Xubuntu桌面环境出现了这样那样的异常,可能依然是那些变成了root所有的用户文件导致的。几经修理,却是解决了一个问题,又出现了新的问题,最后连Xubuntu和Gnome桌面环境都全部丢失(只剩下Xfce桌面),而且网络适配器也不再工作。如此这般,再修下去毫无益处,不如重装。幸好这个系统只是用来测试软件的,并没有存放任何重要文件。这次经历,让我体会到了那种”生小病住院,这治那治,病却越治越多,最后不治身亡“的无奈。以本篇博文,记录下这段时间使用Linux的四点心得。

  1. 备份,备份,还是备份:在改动硬件(比如虚拟硬盘VDI)和全局文件(包括桌面程序和相关的用户配置)前,一定要对系统进行备份,以便在操作失败后能够完整回退。这是基本的工程安全守则。想着”大丈夫,大丈夫です“(没事的,没事的)是不行的——这次Xubuntu系统崩溃,便是这种侥幸心理的后果。一个不经意的致命错误,可以像破坏藏传佛教里的坛城沙画一样简单。但要修复回去,几乎是不可能了。对于虚拟机而言,备份是相当容易的:只需要复制虚拟硬盘即可。
  2. 用分区来隔离文件:“治大病须猛药“。重装Linux系统,常常需要格式化系统盘。盘上的用户数据,自然就荡然无存了。因此,对磁盘合理分区,也是保护用户程序和数据的方法。不仅如此,在系统盘system.vdi之外,我为VirtualBox上的虚拟主机建立并挂载(mount)了另外两个ext4格式的磁盘(program.vdi和data.vdi),从而方便在不同的Linux虚拟机之间传递数据。
  3. 对系统级命令要特别小心:这条关于sudo命令的经验包含两层意思。首先,再执行一条系统级命令前,要理解它到底会做什么。在执行命令前后,还需要留意被它影响的文件。我有一个坏毛病,在遇到问题时,会上网搜解决方案,然后把别人提到的各种命令迫不及待地敲一通,不太注意它们的细节。结果有时会是灾难性的。其次,是系统管理的保守主义:我认为要尽量避免改动系统配置和文件,尽管在你眼中,它们有时候是不完美的。与Windows比起来,Linux为用户开放了强大的命令行功能。在方便管理的同时,也可能会造成严重的系统错误。所以,适当地维持保守心态,有助于系统长期的平稳运行。如果操作系统是用来工作的,那么我们更应该关注它的应用,而不是它看起来有多完美、内容有多整洁,不是吗?
  4. 避免在主操作系统和虚拟机的共享文件夹中编译程序或文件:按最初的设置,我在Xubuntu虚拟机和Win10主系统共享的一个文件夹中编写Rmarkdown文件并用bookdown程序包编译成网站。然而,尽管这样的设置看起来很方便,但我很快发现,因为不明确的原因,有时在虚拟机上编译网站时出现的软件故障(比如对编译器的不当配置),会影响到我在Windows系统上的编译,哪怕Rmarkdown文件和YML配置文件本身并没有任何问题。因此,我还是决定把这个共享文件夹只用于传递文件,而编译工作仅在指定的操作系统的独立文件夹下进行(比如,总是从这个共享文件夹里把所需的程序文件拷贝到Windows下的项目文件夹里,再进行编译)。另外,Ubuntu的onedrive程序并不如Windows下的OneDrive程序可靠——文件同步有时会出现各种问题。因此,我还是推荐用本地共享文件夹来传递文件。
  5. sudo命令提供必需的环境变量:在Ubuntu系统中,通过sudo来运行命令时,被运行的命令并不能直接继承用户当前的环境变量,从而有可能发生找不到相应路径的问题。比如,下面的例子显示了,在加载了MUMmer环境模块后,PATH环境变量在用户环境与sudo环境下的区别。这时,如果被运行的命令依赖特定的路径(比如示范中MUMmer的安装位置/mnt/program/MUMmer3.23),就需要使用sudo env PATH=[your path]:$PATH [your program]命令来补充需要的路径信息。
$ module load MUMmer/3.23

$ echo $PATH
/mnt/program/MUMmer3.23:/mnt/program/python3.6.8:/home/yu/.local/bin:/usr/local/Modules/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

$ sudo bash -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

最后,我还想提一点跟系统管理无关,但在生物信息学工作中有用的感受:尽管功能相似,但环境模块(environment module)更适于服务器向用户提供统一的软件资源,而Conda更适合用户搭建个人的软件环境(比如,用于测试新软件或运行特定的分析工具)。