说起来,我从2010年开始接触 Linux,第一块敲门砖是 Ubuntu 10.10,后来换到 11.04,中间也试过其他主流发行版。进了实验室之后开始用 CentOS,从 5 到 6 再到现在的 7。算下来也有四年了,前三年基本就是瞎折腾——浪费了大把时间,倒也攒了些教训。现在年纪大了,不太想再折腾了,只希望配好一套环境之后能一直用下去。
为什么要写/读这一篇
用 CentOS 的人多少都踩过几个坑,或者有些洁癖受不了的事儿:官方源里的软件版本太老,满足不了功能需求;多个源的包互相打架版本冲突;手动编译软件默认把文件散落在 /usr/local 的不同目录下,更新和删除都麻烦。经历过几次重装系统之后,我把自己那套软件安装的方法和原则整理了一下——谈不上多高深,但至少能保证系统稳定、整洁,也省得因为强迫症又重装一遍。
下面的内容只针对 CentOS 7,对其他发行版或许能有点参考价值。
官方源
CentOS 自带四个官方源,默认开启的有 base、updates、extras,里面大概有 9000 个软件包,最稳定也最值得信赖。所以只要官方源里有的,直接 sudo yum install PackageName 就好,别绕弯子。
第三方源
官方源再好也满足不了所有需求,第三方源就是必要的补充。但第三方源有两个坑:一是跟官方源相同的包可能被替代,二是多个第三方源之间可能有冲突。这两个问题一旦出现,后果经常很严重。所以选第三方源得守两条规矩:
- 只选可靠的,确保它不会替换官方源的包;
- 尽量少用,以免源之间互掐。
就 CentOS 7 来说,下面这几个是安全的选择:
大型第三方源(不替换官方源,且相互无冲突)
- EPEL:6500 多个软件,科研必备。
- ELRepo:几十个硬件驱动程序。
- Nux Dextop:多媒体相关软件包(跟 EPEL 个别包有冲突,但可以忽略)。
小型第三方源(只含个别软件,确认无冲突)
- Google Chrome:就一个 Chrome。
- Adobe:就一个 Flash 插件。
- Dropbox:就一个 Dropbox。
只要软件在 EPEL、ELRepo 或这些小型源里,直接添加源然后 sudo yum install PackageName 就行。
官方 rpm 包
很多非开源软件在官方源或 EPEL 里找不到,但官网会提供对应系统的 rpm 包。比如 WPS for Linux。下载后直接 sudo rpm -i PackageName.rpm,rpm 会自动检查依赖,如果依赖包在已有源里能找到,就会自动装上。唯一的小麻烦是不能用 yum 更新,得手动处理。不过像 Google、Dropbox、Adobe 这些,安装时也会顺手把它们的源加进来,后续更新、删除就方便多了。
解压即用
有些软件只提供压缩包,解压之后直接跑二进制文件。很多 Ja va 程序和商业软件都是这么干的。比如 sublime_text、pycharm、mendeley、TauP、sac——解压后把文件夹扔到 /opt,再把 bin 目录加到 PATH 里就能用。像 Mathematica、Matlab、Intel Studio 这类,自带安装脚本,执行一下就行。Linux 下的惯例是把商业软件或第三方软件装在 /opt,照这个习惯来就好。
第三方 rpm 包
如果 CentOS 源和 EPEL 源里都没有,官网也没提供 rpm 包,但其他第三方源有,那就得分情况讨论:
- 如果那个源只有几个包,并且确定跟现有源不冲突,直接添加源。
- 如果源里包很多,很可能跟官方源或 EPEL 冲突——不添加。
- 如果目标包依赖简单,直接安装那个 rpm 包;如果依赖复杂(比如依赖源里的其他包),就放弃,换别的方法。
第三方包管理器
CentOS 用 yum、Ubuntu 用 apt-get,但近年来出现了一些跨发行版的包管理器,比如 Linuxbrew、Gentoo Prefix、pkgsrc。这里重点说说 Linuxbrew。
Linuxbrew
Linuxbrew 是从 macOS 上的 Homebrew 移植过来的,可以当作系统包管理器的补充。特点包括:所有软件装在 ${HOME}/.linuxbrew 下、版本很新、支持 install/uninstall/info/list/update/upgrade 等基本操作,而且没有的包可以自己写 formulae。但有个坑:它会自己内部解决依赖,比如用 linuxbrew 装 terminator,它发现 terminator 依赖 Python,尽管系统已经有 Python 了,它还是会再装一份,然后 Python 又依赖更多……结果 home 下塞了一大堆东西。而且 linuxbrew 是从源码编译的,速度偏慢。
编译源码
前面几种方法基本能覆盖 99% 的软件。如果还没装,那就问问自己:真的非它不可吗?如果不是,就别折腾了。要是必须,那就手动编译吧。常见的步骤是:
tar -xvf xxxx.tgz ./configure --prefix=/opt/xxxx make sudo make install
很多软件默认安装到 /usr/local,结果 bin、lib、share、man 散落一地。这种方式对后续的更新和卸载极不友好。所以个人习惯在 configure 时指定 --prefix 到自己想要的路径(比如 /opt),卸载时直接删目录,更新时删了重编。麻烦的是需要手动把 bin 加到 PATH 里,可能还要改 LD_LIBRARY_PATH。好在需要手动编译的软件很少,这点代价可以接受。
编译代码(小工具)
这个标题起得有点随意……其实指的是那些编译完只产生一个二进制文件的小代码包。这类东西就没必要往 /opt 里装了。更合适的做法是在 home 下建个 bin 目录,加进 .bashrc,然后把编译好的可执行文件复制进去:
mkdir ${HOME}/bin
echo 'export PATH=${HOME}/bin:$PATH' >> ~/.bashrc
比如我 ${HOME}/bin 里放的东西:distaz(计算震中距和方位角)、pssac(在 GMT 中绘 SAC 文件)、rdseed(SEED 转 SAC)、win2sac_32、catwin32(Hi-net 数据处理)、st(sublime_text 的软链接)、wlt.pl(校内网络登录脚本)、以及 Lupei Zhu 老师的 fk、fk.pl、syn、tra v 等程序。注意别什么都往里放——bin 目录只放常用命令或通用工具。
自成系统的软件
有一类软件自带模块/包管理器的,比如 TeX、Perl、Python。它们的模块生态是最大的优势,所以通常建议手动安装并用各自的包管理器管理模块。为什么不直接用系统源里的版本?原因有两个:系统源不可能包含该软件的所有模块;系统源里的模块更新严重滞后。
如果用系统自带的版本,再用软件自带的包管理器装模块,就会造成部分模块由 yum 管理、部分由自带管理器管理——版本不一致,很容易导致依赖冲突。所以这类软件应该单独安装:
- TeXLive:通过 ISO 镜像安装,用自带的 tlmgr 管理包。
- Perl:通过 plenv 安装最新版,用 cpanm 管理模块。
- Python:通过 pyenv 安装最新版,用 pip 管理模块。
例外
有规则就有例外。比如 mosquito-myrepo 这个私人维护的源,里面含了中文输入法、QQ、飞信、为知笔记、有道词典、百度云以及一堆音视频播放器,对国内用户来说确实方便。但它依赖除 EPEL 之外的第三方源,容易导致包冲突。对这类源,保留态度得谨慎——爱恨交织。
总结
简单梳理一下思路:
- 先给系统加 EPEL、Nux Dextop、ELRepo 以及个别靠谱的小型第三方源。
- 能从源里装的就从源里装(yum install)。
- 源里没有的,优先找官方 rpm 包。
- 没有 rpm 包的,试试 Linuxbrew 这类第三方管理器。
- 能不动手编译的就别编译,真到那一步也尽量指定 prefix 到
/opt,方便管理。
按照这个流程,绝大多数软件都能干干净净地装好,系统也经得起折腾。
