内容纲要

🗂 本文目录:Linux 指南 >


源代码构建

一种常见的 UNIX 和 Linux 的软件资源(源代码、构建文件、文档以及配置模板)分发方式为采用压缩过的归档文件形式发布,通常是以 gzip 压缩的 tar 归档(.tar.gz.tgz 文件)。

一般的安装步骤为:

  1. 获取源代码归档文件
  2. 解压归档文件
  3. 进入目录
  4. 使用 ./configure --help | more 查看选项
  5. 使用 ./configure 配置
  6. 使用 make 编译
  7. 使用 make install 安装

关于 ./configure 是个安装配置,比如使用 --prefix 可以指定到指定目录,可以使用选项 ./configure --help | more 查看支持的其他选项。

安装示例

此处以安装 iPerf3 为例:

# 下载源代码压缩包
$ wget https://iperf.fr/download/source/iperf-3.1.3-source.tar.gz

下载完编译安装所用的归档文件后,使用 -C 参数指定解压目录到 /usr/local/src/,根据 Linux HFS 该目录用于存放本地安装软件的源代码,一般通过归档文件分发的软件可以存放源代码在此进行编译

# 解压缩
$ sudo tar -xaf iperf-3.1.3-source.tar.gz -C /usr/local/src/

# 进入解压的目录中
$ cd /usr/local/src/iperf-3.1.3

构建配置也时常需要微调,使用 ./configure --help 可以查看特定软件包的可用配置项,如最常用的 --prefix=<路径名> 可以指定软件的安装位置,如 ./configure --prefix=/usr/local/bin/

构建配置及编译、安装:

# 构建配置
$ sudo ./configure

# 编译
$ sudo make

# 安装
$ sudo make install

处理遇到的问题

./configuremake 的过程中有可能出现报错,这时候就需要根据报错信息排查解决问题。

仍以 iPerf3 为例,常见遇到的问题如下:
问题 1: configure: error: no acceptable C compiler found in $PATH./configure: error: C compiler cc is not found
问题 2: make: command not found

以使用 APT 为例:

$ sudo apt install build-essential

💡 有些人会在安装 build-essential 后仍会看到 C compiler cc is not found 的提示,这是缺少权限所致,使用 sudo ./configure 或使用拥有足够权限的帐户再次运行即可。

报错日志很重要,通过报错日志解决问题也是一个良好习惯,如果你不知道报错信息是什么意思就复制它到搜索引擎搜一下吧。

另外,以上只是一些通用步骤,在实际安装不同软件时最好查看软件的官方使用说明,比如开源在 Github 的软件都会有一份 README.md 说明指导使用,一些软件可能还需要一些第三方依赖库,阅读使用说明是一个良好习惯并因此可少走不少弯路。

在编译安装成功后可以使用命令查看软件的版本以此查看是否安装成功:

# -v 等同于 --version 用于查看软件的版本号,大部分软件都有该参数
$ iperf -v
# 或
$ iperf3 -v

返回:iperf 3.1.3

能看到版本号则表示安装成功了。

问题 3: 运行 iperf3 时可能会运行报错:iperf3: error while loading shared libraries: libiperf.so.0: cannot open shared object file: No such file or directory,此时解决方法为:

# 在运行 iperf3 前先运行 ldconfig
$ sudo /sbin/ldconfig
# 或是将 /usr/local/lib 加入 LD_LIBRARY_PATH 之中
$ export LD_LIBRARY_PATH=/usr/local/lib

通常编译安装对于开发人员来说没什么问题,但最终用户和管理员就觉得不方便了,只要软件有新版本发布,就必须在每个系统上手动编译并构建源代码,这个过程既无趣又容易出错。

软件包管理

打包系统(packaging system)的出现简化并推推进了软件管理工作。软件包中含有运行软件所需要的全部文件,包括预编译好的二进制文件、依赖信息、可由管理员定制的配置文件模板等。其中最重要的可能要算打包系统力图使安装过程尽可能的原子化(atomic),如果安装发生了错误,可以撤销(backed out)或是重新安装软件包,当有新版本时只用更新软件包即可,非常简便。

在 Linux 中最常见的有两种软件包格式:.deb.rpm。这是一种双层(dual-layer)的全能配置管理工具。下层的工具负责安装、卸载、查询软件包,上层对应系统负责从 Internet 上查找并下载软件包、分析软件包之间的依赖关系、更新系统中所有的软件包。

dpkg:管理 .deb 软件包

以 VirtualBox 虚拟机为例,在官网上找到相对应的软件版本下载

# wget 是一个从网上下载文件的工具
$ wget https://download.virtualbox.org/virtualbox/6.1.4/virtualbox-6.1_6.1.4-136177~Ubuntu~bionic_amd64.deb

virtualbox-6.1_6.1.4-136177~Ubuntu~bionic_amd64.deb 文件名拆解来看:

  • virtualbox 软件名
  • 6.1_6.1.4-136177 软件版本
  • Ubuntu~bionic Linux 发行版
  • amd64 系统架构
  • deb 软件包管理格式

软件包名也是有所需要注意的地方,如上需要最注意后两位也就是 amd64debamd64 适用于 x86 架构的 64 位系统,也就是不能安装在其他架构比如 ARM 上,而 deb 如前所述目前 Linux 两大派系 Debian(包括 Ubuntu、Mint、Deep 等)和 Redhat (包括 Fedora、CentOS 等)是分别使用 deb 和 rpm 的软件包格式,默认是不包含另一套包管理工具的,也就是说不能把 deb 软件包拿到默认情况下使用 rpm 包管理的发行版上使用,反之亦然。

在确定了软件包获取正确后开始安装软件:

# 使用 dpkg 命令,-i 参数表示 install 安装,-i 等同 --install
$ sudo dpkg -i virtualbox-6.1_6.1.4-136177~Ubuntu~bionic_amd64.deb

⚠️ 注意:但有时候你可能会遇上依赖问题,如下类似的报错:

dpkg: 依赖关系问题使得 virtualbox-6.1 的配置工作不能继续:
 virtualbox-6.1 依赖于 libcurl4 (>= 7.16.2);然而:
  未安装软件包 libcurl4。
 virtualbox-6.1 依赖于 libqt5core5a (>= 5.9.0~beta);然而:
  未安装软件包 libqt5core5a。
 virtualbox-6.1 依赖于 libqt5gui5 (>= 5.4.0);然而:
  未安装软件包 libqt5gui5。
 virtualbox-6.1 依赖于 libqt5opengl5 (>= 5.0.2);然而:
  未安装软件包 libqt5opengl5。
 virtualbox-6.1 依赖于 libqt5printsupport5 (>= 5.0.2);然而:
  未安装软件包 libqt5printsupport5。
 virtualbox-6.1 依赖于 libqt5widgets5 (>= 5.7.0);然而:
  未安装软件包 libqt5widgets5。
 virtualbox-6.1 依赖于 libqt5x11extras5 (>= 5.6.0);然而:
  未安装软件包 libqt5x11extras5。
 virtualbox-6.1 依赖于 libsdl1.2debian (>= 1.2.11);然而:
  未安装软件包 libsdl1.2debian。
dpkg: 处理软件包 virtualbox-6.1 (--install)时出错:
 依赖关系问题 - 仍未被配置
正在处理用于 systemd (237-3ubuntu10.39) 的触发器 ...
正在处理用于 ureadahead (0.100.0-21) 的触发器 ...
正在处理用于 gnome-menus (3.13.3-11ubuntu1.1) 的触发器 ...
正在处理用于 desktop-file-utils (0.23-1ubuntu3.18.04.2) 的触发器 ...
正在处理用于 mime-support (3.60ubuntu1) 的触发器 ...
正在处理用于 hicolor-icon-theme (0.17-2) 的触发器 ...
正在处理用于 shared-mime-info (1.9-2) 的触发器 ...
在处理时有错误发生:
 virtualbox-6.1

这个时候可以先解决依赖问题(安装日志上所提的未安装软件包)后再次安装,对于补齐依赖还可以使用 APT 自动安装所需要的软件包:

# 补齐依赖
$ sudo apt install -f

可以通过 -l 参数查询是否安装了某个软件

# -l 表示 list
$ sudo dpkg -l virtualbox
# 或是
$ sudo dpkg -l | grep virtualbox

可以通过 -r 参数删除指定软件

# -r 表示 remove
$ sudo dpkg -r virtualbox-6.1
# -P 表示 pure 删除软件及其配置文件
$ sudo dpkg -P virtualbox-6.1

⚠️ 注意:在输入到 dpkg -r virtualbox 时可能不知道具体版本号或更具体的包名,这时可以使用 Tab 键列出可选项来补全结果。

在遇到需要处理安装或卸载多个软件包时,使用空格将每个软件包名隔开即可使用一条命令处理多个软件包。

小结

# 使用 -i 安装指定软件
$ sudo dpkg -i <软件包名>

# 使用 -l 查询安装的某个软件包
$ sudo dpkg -l <软件包名>
# 或是
$ sudo dpkg -l | grep <软件包名>

# 使用 -r 卸载指定软件
$ sudo dpkg -r <软件包名>

# 使用 -P 卸载软件及删除其配置文件
$ sudo dpkg -P <软件包名>

RPM:管理 .rpm 软件包

RPM 全称 RPM Package Manager,.rpm.deb 功能类似,rpm 命令可以完成软件包的安装、验证及状态查询。rpm 选项之间的关系非常复杂,只能选用特定的选项组合,最好是把 rpm 想象称恰好采用了相同名字的多个不同命令。

使用 -i (install)安装指定软件

$ sudo rpm -i <软件包名>

使用 -q (query)查询指定软件

$ sudo rpm -q <软件包名>

# 列出系统中以安装的所有软件包
$ sudo rpm -qa <软件包名>

使用 -e (erase)卸载指定软件

$ sudo rpm -e <软件包名>

使用 -U (upgrade)更新指定软件,比如找到软件包的新版本,可以使用 rpm -U 来更新替换旧版本。

$ sudo rpm -U <软件包名>

但可能并不能一帆风顺的成功更新,因为新版本可能需要新的依赖,此时尽管你可以使用强制参数选项 --force,但这并不是推荐的做法,可以先查询所依赖但那些软件包但更新版本

$ sudo rpm -q --whatrequires <软件包名>

高级软件包管理系统

像 APT(Advanced Package Tool) 和 DNF(Dandified YUM) 等这样的基础软件包(metapackage)管理系统有一些共同目标:

  • 简化软件包的定位与下载;
  • 实现系统更新或升级过程的自动化;
  • 促进软件包之间依赖关系的管理;

显然像这样的系统所面对的不仅仅是客户端的命令,它们还要求发行版的维护人员以一种统一认可的方式组织好提供的软件。

而且这样的系统还允许存在多个的软件仓库,包括放置在本地网络的,这也促成了用户可以搭建一个用于内部的发布系统,毕竟没有任何一个供应商能够涵盖整个「Linux 软件世界」。

一般而言每个 Linux 发行版都有自己维护的软件库,且和发行版本选择的软件包管理系统携手工作,而软件包管理系统默认配置通常指向一个或多个由发行版控制的知名 Web 或 FTP 服务器。

APT:Advanced Package Tool

高级软件包工具 (Advanced Package Tool,简称 APT),是 Debian 及其衍生产品的主要命令行软件包管理器。它提供了用于搜索、管理和查询软件包信息的命令行工具,以及对 libapt-pkg 和 libapt-inst 库所提供的所有功能的低级访问,而这些功能是更高级别的软件包管理器可以依赖的。

如果使用 APT 管理来自标准仓库镜像中的安装,那么查看可用安装包最简单的方法是,如使用的是 Debian 访问 Debian — Packages 或使用的是 Ubuntu 则访问 Ubuntu Packages Search,网站提供了美观友好的界面,选择你正在使用的发行版代号和想要查找软件包就能列出结果。

软件仓库(源服务器)配置

在使用 APT 前不得不提到 APT 最重要的配置文件:/etc/apt/sources.list,以 Debian 10 官方镜像为例它的内容如下:

deb http://deb.debian.org/debian/ buster main
deb-src http://deb.debian.org/debian/ buster main

deb http://security.debian.org/debian-security buster/updates main
deb-src http://security.debian.org/debian-security buster/updates main

# buster-updates, previously known as 'volatile'
deb http://deb.debian.org/debian/ buster-updates main
deb-src http://deb.debian.org/debian/ buster-updates main

# This system was installed using small removable media
# (e.g. netinst, live or single CD). The matching "deb cdrom"
# entries were disabled at the end of the installation process.
# For information about how to configure apt package sources,
# see the sources.list(5) manual.

该配置文件告诉了 APT 应该从哪里获取软件包,具体构成如下:

  • type 字段:即软件包类型,debdeb-src 表示 .deb 类型的软件包、rpmrpm-src 表示 .rpm 类型的软件包;
  • uri 字段:指向可以从中获取到软件包的文件、HTTP 或 FTP 服务器的 URL;
  • distribution 字段:即发行版代号,如上述内容中的 buster 是 Debian 10 的代号,每个大版本都会有自己的代号;
  • components 字段:一个可能的组建清单(发行版本内的软件包分类)

举例说明:

deb http://deb.debian.org/debian/ buster main

type uri distribution components

distribution 字段和 components 字段帮助 APT 遍历软件仓库中文件系统的层次结构,这个结构的布局是有标准可循的。distribution 字段是根发行版给每个发行起的 working title,如 Debian 10 的 buster,Ubuntu 20.04 的 focal。components 字段的可用组件通常叫做 main、universe、multiverse、restricted。

在 Ubuntu 中除了基本的开源软件的 universe 组件还会有 multiverse 组件以使用一些非开源内容,如 VMware 等,也就是说如果想使用一些未受支持、存在受限许可的软件包可以加入 universe 和 multiverse 仓库。而 Debian 根据 《Debian自由软件指导方针》,所有包含在 Debian 正式发行版中的软件包,都是自由软件。

另外关于 uri 默认的配置也需要注意,默认的服务器配置可能并不适合你所在的区域,如压根就连接不上或速度极其缓慢,好在全球各地都有开源镜像站(甚至一些云服务商有自己本地的镜像站),这时候就近选择一台开源镜像服务器就可以加快速度提升使用体验。

例如 Debian 的 Debian worldwide mirror sites 和 Ubuntu 的 Official Archive Mirrors for Ubuntu 官方公布了位于全球各地的全球镜像站,可以放心的使用上面列出的镜像站或使用你自己信任的镜像站。

此处以使用「网易开源镜像站」为例通过命令快速修改源配置,特别是如果你还不熟悉 vim 等编辑器的使用,这是个比较友好的方法:

可以先使用 cat /etc/apt/sources.list 查看配置中的域名是什么,如前所述我所安装的 Debian 10 中默认的地址为 deb.debian.orgsecurity.debian.org,此处我将将其修改为 mirrors.163.com

# 将 sources.list 中的 deb.debian.org 替换为 mirrors.163.com
$ sudo sed -i s/deb.debian.org/mirrors.163.com/g /etc/apt/sources.list

# 将 sources.list 中的 deb.debian.org 替换为 mirrors.163.com
$ sudo sed -i s/security.debian.org/mirrors.163.com/g /etc/apt/sources.list

# 查看源文件以确认修改成功
$ cat /etc/apt/sources.list

# 更新软件源
$ sudo apt update

⚠️ 这里需要提到的是,如 Debian 的 security.debian.org 和 Ubuntu 的 security.ubuntu.com 这样的地址是用于安全更新的,如 Linux Mint 等发行版有提供图形化的源服务器修改工具,在修改时上述用于安全服务的地址是不会被修改到的,包括一些 Linux 相关的专业书籍提到,一定要确保官方的安全服务器作为源加入,以便能够访问最新的安全补丁。

附言:即便如此我个人依然使用开源镜像站,因为默认地址在我这实在太慢了

APT 使用

更新升级

# 更新软件源
$ sudo apt update

# 用于安装当前系统上安装的所有包的最新版本
$ sudo apt upgrade

# 与 apt upgrade 功能相似,但除了执行升级功能外,还智能地处理与新版本包的依赖关系的变化;
# 如果有必要,它会试图以牺牲不太重要的包为代价,升级最重要的包。
# 因此,dist-upgrade 命令可能会删除一些软件包。
$ sudo apt dist-upgrade

 # 更新指定的软件包
$ sudo apt upgrade <软件包名>

# 可以使用 & 符号将多条命令一起执行
# 刷新软件源并更新需要更新的软件
# -y 参数用于自动确认提示,可用于 corn 定期更新
$ sudo apt update & sudo apt dist-upgrade -y

软件查找以及软件信息查看

# 查找某个软件包
$ apt search <软件包名>

# 显示某个软件的信息
$ apt show <软件包名>

# 列出指定(含已安装)的软件包
$ apt list -a <软件包名>
# 可以使用通配符查找包含该名字的包,如和 Nginx 相关的包
$ apt list nginx*

软件安装及卸载

# 安装某个软件包
$ sudo apt install firefox

# 卸载某个软件包
$ sudo apt remove firefox
# 卸载某个软件包及其配置文件
$ sudo apt purge firefox # 或 apt --purge remove firefox

# 卸载不需要的包
$ sudo apt autoremove

DNF:Dandified YUM

DNF 是 YUM 的下一个主要版本,它是一个基于 RPM 的 Linux 发行版的软件包管理器。

它大致保持了与 YUM 的 CLI 兼容性,并为扩展和插件定义了一个严格的 API。

# 检查可以更新的软件包
$ dnf check-update

# 更新可以升级的软件包
$ sudo dnf update # 或 dnf upgrade,更新系统中所有可以更新的软件包
$ sudo dnf update firefox # 更新指定的软件包

# 查找某个软件包
$ dnf search bash
# 显示某个软件包信息
$ dnf info bash
# 列出指定已安装的软件包
$ dnf list bash

# 安装某个软件包
$ sudo dnf install nginx
# 卸载某个软件包
$ sudo dnf remove nginx  # 或 dnf erase nginx

# 卸载不需要的包
$ sudo dnf autoremove

说到 Red Hat 系的发行版就不得不提到 EPEL(Extra Packages for Enterprise Linux),这是一个由 Fedora 特别兴趣小组创建、维护以及管理针对企业版 Linux 的一个高质量附加软件的包集。EPEL 是 Fedora 的一个精选包,但只有那些不在 RHEL 或其分层产品中的包,以避免冲突。所以你不会在 EPEL 中找到已经和 RHEL 一起发布的新版本的东西。

以 RHEL 来说,大多数人都知道 Fedora 是 RHEL 主要发行版的上游版本。出于多种原因,Red Hat 为 RHEL 提供的包集比在 Fedora 中的包集要小,因为 Fedora 中的很多软件在企业环境中是不需要的,或者不属于 RHEL 的范围。

如果作为 Fedora 用户并希望在 RHEL 工作站上安装 ImageMagick 或 Chromium 就需要 EPEL。也就是说,包括但不限于 Red Hat Enterprise Linux (RHEL)、 CentOS 和 Scientific Linux (SL)、 Oracle Linux (OL) 的发行版可以添加 EPEL 仓库以使用更多的软件包。

但同时需要注意,这是一个开源社区主导的项目,它为用户提供了很多好处,但没有生产准备或技术支持的保证。所以 EPEL 项目建议 EPEL 的用户订阅 EPEL-announce 邮件列表,以了解即将发生的问题,并在更新产生影响之前有时间进行测试。

# 启用 EPEL 仓库
$ sudo dnf install epel-release

# 启用 PowerTools 存储库,因为 EPEL 包可能依赖于这些存储库中的包
$ sudo dnf config-manager --set-enabled powertools

Web 安装脚本

跨平台软件逐渐开始提供一种由脚本驱动的快速安装方法。脚本可以使用 curl、fetch 或 wget 从 Web 上进行下载。

这种安装方式很好,但也有几个问题需要注意:

  1. 脚本安装方式通常没有留下可供之后参考的记录,所以如果发行版提供了软件的打包版本就不建议使用 Web 方式了,软件包便于跟踪、更新和删除。
  2. 一些安装脚本是以 HTTP 的形式公开的,这可能存在被劫持,如果可能就尽量使用 HTTPS 的 URL。
  3. 比较常见的当你使用 SSH 连接上了服务器,在使用脚本安装时遇到网络抖动,从而断开了与服务器的连接,这时 curl 虽然只输出了部分内容但 root shell 仍在运行,这时它可能安装失败,这种无法预测的情况可能造成不良影响,解决方法是使用 Screen,即便遭遇断连也可以使会话恢复。

查找软件是否已安装和位置

可以使用 shell 的 which 命令查找相关的二进制程序是否已经在搜索路径中,如

$ which vim
/usr/bin/vim

当然这并不一定准确,因为如编译安装的程序不一定在 $PATH 中。

使用 whereis 会搜索除 shell 的搜索路径以外更大范围的系统目录。

$ whereis vim
vim: /usr/bin/vim.tiny /usr/bin/vim /usr/bin/vim.basic /etc/vim /usr/share/vim /usr/share/man/man1/vim.1.gz

延伸