GNU/Linux 基础 — 管理二进制软件包

概述

本章,您将学习有关二进制软件包的管理。

在 GNU/Linux 操作系统中,可通过这两种方式安装您需要的软件:

  1. 从存储库下载软件包并安装到本地计算机中
  2. 源码包编译后安装到本地
不同的名称定义
存储库:也称软件源或软件仓库,是一个存放已经被人预先编译好的二进制软件包的地方。

Q:什么是软件包?什么是源文件?什么是源码包?

软件包:指开发者预先将一组源文件编译成可执行的机器语言并打包成特定格式的二进制文件。若无特殊说明,GNU/Linux 中的软件包特指二进制软件包。用听得懂的话来说,二进制软件包就类似别人预先组好但不能调整结构的装有一堆工具的工具箱,来完成特定的任务或工作。

源文件:人类可读的单个代码文件(如 .c、.py、.java),它可能只是整个项目的一个代码片段或模块,需编译或解释才能运行在计算机上。

源码包:将整个项目的源文件与相关文件(比如 Makefile、configure 等构建文件;比如 README、LICENSE 等文档文件)打包好的一个经过压缩的归档文件,如 .tar.gz 、.tar.xz 等。

软件包与源码包的对比如下:

类型 优点 缺点
二进制软件包 安装速度快;安装、卸载、升级等很方便;借助包管理器可以自动解决依赖问题;稳定性与兼容性经过测试 不能看见源代码;安装之后功能已经固定,无法按需定制
源码包 自由查看、修改源代码;自由添加或扩展功能;性能释放比二进制软件包要好;学习别人的代码并提高代码能力 安装复杂且费时;需要解决复杂的依赖问题;对新手不友好

rpm 本地包管理器

rpm 命令:红帽上下游发行版中用于管理本地 RPM 软件包的命令行工具。请注意下 rpm 这个专有术语,有时它指二进制软件包的格式后缀(如 xxxx-xxx-xxx.rpm),有时指 rpm 这个命令行工具。

在正式使用 rpm 命令前,我们需要了解下二进制软件包的命名规范,如下所示:

[Package_Name]-[Version]-[Release].[OS].[Arch].rpm

[Package_Name]-[Version]-[Release].[OS].[Arch].src.rpm

有时在包全名中见到一些其他的名称,如:

  • devel – 表示这个 RPM 包是软件的开发包
  • noarch:说明该 RPM 软件包可以在任何架构上安装

包全名(Full Package Name):二进制软件包的完整名称,如 tree-1.7.0-15.el8.x86_64.rpm
包名(Package Name):软件包的名称,如 tree

有些命令的操作对象是 包全名,有些命令的操作对象是 包名,这点需要注意。

Q:什么时候需要包全名?什么时候需要包名?

操作系统中从来没有安装过该软件包时,相关命令需要使用包全名。比如使用 rpm 命令进行安装或升级时需要包全名。

操作系统已经安装过该软件包时,相关命令需要使用包名,因为相关软件包的信息存放在 /var/lib/rpm/ 数据库目录当中,所以不需要使用包全名。比如使用 rpm 命令进行查询或卸载时需要包名。

rpm 命令的使用语法如下:

Shell > rpm [options]  <Package-Name> | <Full-Package-Name>

安装、升级、卸载软件包

相关选项:

  • -i – 安装
  • -v – 显示安装过程中的细节
  • -h – 显示进度条
  • -U – 升级
  • -e – 卸载

安装一个或多个软件包 – rpm -ivh <Full-Package-Name> ...
升级一个或多个软件包 – rpm -Uvh <Full-Package-Name> ...
卸载一个或多个软件包 – rpm -e <Package-Name> ...

在安装软件的过程中,由于 rpm 是本地的包管理器,因此我们需要手动解决依赖性问题 —— 即在安装或升级过程中会出现诸如 "failed dependencies" 这样的提示。

这里我们需要了解下 RPM 包的依赖:

  1. 树形依赖a --> b --> c。安装软件包 a 时提示需要先安装软件包 b,安装软件包 b 提示需要先安装软件包 c,互相依赖。这种依赖比较好解决,直接在一条命令中执行 rpm -ivh a.rpm b.rpm c.rpm 就好了
  2. 环形依赖a --> b --> c --> a。直接在一条命令中执行 rpm -ivh a.rpm b.rpm c.rpm 就好了
  3. 模块依赖 – 去 这个网站 查找即可

Q:为什么 RPM 软件包会出现依赖问题呢?

因为软件应用程序几乎总是依赖于另一个软件或库,如果操作系统上没有找到所需的程序或共享库,那么在安装目标应用程序之前必须满足该先决条件。其实 Windows 中的 .exe 二进制软件包在安装之前也会进行依赖项的环境检查,若不符合或未找到相关的依赖项,则在安装过程中会提示安装失败,在安装一些大型的应用程序时会比较常出现。

查询软件包

相关选项:

  • -q – 查询相关的程序是否安装过,例如 rpm -q openssh
  • -a – 与 -q 搭配使用,查询所有已安装的 rpm 包,a 即 all 的意思
  • -i – 与 -q 搭配使用,查询对应已安装的 rpm 包的详细信息,i 即 infomation 的意思
  • -l – 与 -q 搭配使用,查询对应已安装的 rpm 包的释放的文件列表,l 即 list 的意思。
  • -p – 与 -ql 搭配使用,查询未安装的 rpm 包的释放的文件列表,需要注意,命令后面需要使用包全名,例如 rpm -qlp tree-1.7.0-15.el8.x86_64.rpm
  • -f – 与 -q 搭配使用,查询操作系统中某一系统文件属于哪个 rpm 包,f 即 file 的意思。比如 rpm -qf /usr/bin/ssh 。这里的系统文件指的是通过二进制软件包释放出来的文件。
  • -R – 与 -q 搭配使用,查询对应 rpm 包的依赖性,可以针对已经已经安装过的 rpm 包,也可以针对未安装的 rpm 包(需要搭配 -p 选项)。比如 rpm -qR openssh-clients 以及 rpm -qRp tree-1.7.0-15.el8.x86_64.rpm

校验软件包的签名

当您从未知的网站或不受信任的位置下载 rpm 二进制软件包时,您不知道该软件包是否被做了篡改,因此,我们需要对软件包做签名的验证,以保证我们下载的软件包是完整的且未被篡改的。

从 RHEL 8.x 开始,您可以使用 dnf download 命令下载具体的软件包。例如您需要下载 wget 软件包,请键入:

# 若需要指定下载的目录位置,请添加 --destdir DESTDIR 或 --downloaddir DESRDIR 选项
Shell > dnf download wget

Shell > ls
wget-1.19.5-11.el8.x86_64.rpm

要对软件包的签名进行校验,需要的前提条件 —— 导入了所需的公钥(这通常不需要系统管理员来操作,但您需要知道这件事)

例如针对上面的 wget-1.19.5-11.el8.x86_64.rpm 做签名校验,请键入:

# 若需要更加详细的消息,请添加 -v 或 -vv 选项
## 当输出信息中有 "digests signatures OK" 时,证明软件包没有问题,未被篡改。
Shell > rpm -K wget-1.19.5-11.el8.x86_64.rpm
wget-1.19.5-11.el8.x86_64.rpm: digests signatures OK

# 我们可以恶意地故意篡改软件包 —— 这可以通过在原始软件包中添加任何内容或从中删除某些内容来实现。请注意!任何以原始软件包不希望的方式变更软件包的行为都会导致其损坏或不完整,例如:
Shell > echo  "change content" >> /root/wget-1.19.5-11.el8.x86_64.rpm

# 当输出信息中出现 "digests signatures NOT OK" 时,您不应该继续使用该软件包,因为它不再受到信任。
Shell > rpm -K wget-1.19.5-11.el8.x86_64.rpm
wget-1.19.5-11.el8.x86_64.rpm: digests signatures NOT OK

校验软件包的变更

上面文字提到的是软件包的签名校验,这里说的是软件包的变更校验。相关选项:

  • -V – 校验软件包

当 rpm 软件包安装过后,rpm 数据库会记录相关文件的初始特征以及变更后的特征,以了解软件包释放出的文件是否被人恶意修改。

Shell > rpm -V chrony
S.5....T.  c /etc/chrony.conf

第一部分(S.5....T):表示验证文件内容中的 8 个信息,若相关信息没有被修改,则会用 . 进行表示。

  • S – 文件大小是否改变
  • M – 文件的类型或文件的权限(rwx)是否被改变
  • 5 – 文件 MD5 校验和是否改变(可以看成文件内容是否改变)。MD5 是互联网的一种加密方式,主要用来进行文件的完整性验证。
  • D – 设备是否改变
  • L – 文件路径是否改变
  • U – 文件的所有者是否改变
  • G – 文件的所属组是否改变
  • T – 文件的修改时间(mtime)是否改变

第二部分:代表变更的文件类型

  • c – 配置文件(config file)
  • d – 普通文件(documentation)
  • g – "鬼"文件(ghost file),非常少见,一般该文件不会出现在 rpm 包里
  • I – 授权文件(license file)
  • r – 描述文件(readme file)

第三部分:代表被修改的文件路径

卸载软件包

安全且正确的做法是键入 -e 选项,支持对一个或多个软件包的卸载:

Shell > rpm -e <Package-Name> ...

需要注意的是,-e 选项默认情况下会移除软件包并检查依赖,例如 a.rpm 依赖 b.rpm ,当您使用 rpm -e a 时会卸载失败,提示 error: Failed dependencies。虽然您可以强制移除某一个软件包(比如 rpm -e --nodeps a),但我们不建议您这样做。

有时您的操作系统进行了升级,需要移除旧版本的内核,可以这样操作:

Shell > grubby --info ALL
index=0
kernel="/boot/vmlinuz-4.18.0-553.45.1.el8_10.x86_64"
args="ro crashkernel=auto resume=UUID=76e2324e-ccdc-4b75-bc71-64cd0edb2ebc $tuned_params"
root="UUID=57d8aec0-891b-4f58-9125-c2d68e81c572"
initrd="/boot/initramfs-4.18.0-553.45.1.el8_10.x86_64.img $tuned_initrd"
title="Rocky Linux (4.18.0-553.45.1.el8_10.x86_64) 8.10 (Green Obsidian)"
id="638c6d5d2b674f77be56174469099106-4.18.0-553.45.1.el8_10.x86_64"
index=1
kernel="/boot/vmlinuz-4.18.0-553.40.1.el8_10.x86_64"
args="ro crashkernel=auto resume=UUID=76e2324e-ccdc-4b75-bc71-64cd0edb2ebc $tuned_params"
root="UUID=57d8aec0-891b-4f58-9125-c2d68e81c572"
initrd="/boot/initramfs-4.18.0-553.40.1.el8_10.x86_64.img $tuned_initrd"
title="Rocky Linux (4.18.0-553.40.1.el8_10.x86_64) 8.10 (Green Obsidian)"
id="638c6d5d2b674f77be56174469099106-4.18.0-553.40.1.el8_10.x86_64"
index=2
kernel="/boot/vmlinuz-0-rescue-638c6d5d2b674f77be56174469099106"
args="ro crashkernel=auto resume=UUID=76e2324e-ccdc-4b75-bc71-64cd0edb2ebc"
root="UUID=57d8aec0-891b-4f58-9125-c2d68e81c572"
initrd="/boot/initramfs-0-rescue-638c6d5d2b674f77be56174469099106.img"
title="Rocky Linux (0-rescue-638c6d5d2b674f77be56174469099106) 8.10 (Green Obsidian)"
id="638c6d5d2b674f77be56174469099106-0-rescue"

Shell > uname -r
4.18.0-553.45.1.el8_10.x86_64

# 如您所见,我目前在使用这个内核索引号为 0 的这个内核 —— 4.18.0-553.45.1
## 我需要将 4.18.0-553.40.1 内核移除
Shell > rpm -e $(rpm -qa | grep ^kernel | grep -v 553\.45)

Shell > sed -i '9s/true/false/g' /etc/default/grub

Shell > grub2-mkconfig -o /boot/grub2/grub.cfg

dnf 包管理器

dnf 包管理器是 yum 包管理器的替代,前者采用 Pythton3.x + C 语言进行开发(libsolv 库以及被称为 SAT 的算法),后者采用 Python 2.x 语言进行开发,因此 dnf 在处理依赖时有着性能高、处理速度快以及内存占用低等优点。在一些较新的发行版中(如 Fedora 41),dnf 还支持并行下载软件包。

dnf 命令

dnf 命令的语法如下:

dnf [options] <command> [<args>...]

这里的 command 即 dnf 的功能项命令,这些功能项命令有些是 dnf 自带的,有些是第三方插件提供的,常用的有:

  1. list 命令

    依据该命令后面选项的不同列出软件包,默认列出操作系统所有可被安装的软件包(dnf list 等同于 dnf list --all)。

    列出当前操作系统已经安装的软件包 —— dnf list --installed

    列出可以升级的软件包 —— dnf list --updates

  2. search 命令

    依据给定的关键字从存储库中搜索软件包,例如 dnf search vim

  3. install 命令

    从存储库中安装一个或多个软件包,例如 dnf install -y tree wget-y 的意思是将所有的交互提示都回答为 yes

    除了可以从存储库中安装软件包外,您可从指定的 URL 安装软件包,比如 dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

  4. info 命令

    查看一个或多个软件包的信息,比如 dnf info wget tree

  5. deplist 命令

    列出软件包的依赖关系,已被弃用,请使用 dnf repoquery --deplist <Package-Name> 作为替代。

  6. repolist 命令

    显示存储库方面的信息,默认显示已经被启用的存储库(dnf repolist 等同于 dnf repolist --enabled)。

    查看所有的存储库 —— dnf repolist --all

  7. history 命令

    显示键入的 dnf 历史命令,默认情况下 dnf history 等同于 dnf history list,这里的 list 还可以是 inforedoreplay, rollbackstore, undo userinstalled 的其中一个。

  8. provides 命令

    查看给定的系统文件属于哪一个软件包,比如 dnf provides /usr/bin/systemctl

  9. remove 命令

    移除当前操作系统中的一个或多个软件包,默认情况下会询问是否连带的依赖包一起卸载,若要应答为 yes,请键入 -y,比如 dnf remove -y vim tree

  10. autoremove 命令

    自动移除那些曾经被当作依赖项但现在不再使用的软件包。比如 dnf autoremove -y

  11. makecache 命令

    为新添加的或元数据过时的存储库生成缓存。

  12. updateupgrade 命令

    将操作系统中的一个或多个软件包进行升级,比如 dnf update -y 将升级操作系统中所有可升级的软件包

  13. grouplistgroupinstallgroupremovegroupinfo 命令

    这些命令主要的操作对象是软件包组,软件包组指的是为特定场景或环境而准备的一组软件包。

    在 RockyLinux 8.x 中有这些软件包组:

    Shell > dnf grouplist
    Available Environment Groups:
       Server with GUI
       Server
       Workstation
       KDE Plasma Workspaces
       Virtualization Host
       Custom Operating System
    Installed Environment Groups:
       Minimal Install
    Available Groups:
       Container Management
       .NET Core Development
       RPM Development Tools
       Development Tools
       Graphical Administration Tools
       Headless Management
       Legacy UNIX Compatibility
       Network Servers
       Scientific Support
       Security Tools
       Smart Card Support
       System Tools
       Fedora Packager
       Xfce
  14. clean 命令

    清除缓存数据,通常我们会使用 dnf clean all 来清除所有的数据缓存,然后键入 dnf makecache 生成新的缓存。

  15. download 命令

    将存储库中的软件包下载到本地计算机而不安装它们。您可以使用 --destdir DESTDIR--downloaddir DESRDIR 选项来指定保存的路径,比如 dnf download tree --downloaddir /tmp/

  16. repoquery 命令

    rpm -q 命令类似,给定字符串并从存储库中搜索指定的包,然后列出相关的信息。比如查看依赖 dnf repoquery --deplist <Package-Name>,查看软件包(无论这个软件包是否已经安装到操作系统)释放出的文件路径 dnf repoquery --list <Package-Name>

  17. config-manager 命令

    以命令行方式管理存储库,包括对存储库的添加与删除,对某一个存储库的启用与关闭等。

    例如需要添加一个新的存储库:

    Shell > dnf config-manager --add-repo URL

    永久关闭某一个已经被启用的存储库:

    Shell > dnf repolist
    repo id                                      repo name
    appstream                                    Rocky Linux 8 - AppStream
    baseos                                       Rocky Linux 8 - BaseOS
    docker-ce-stable                             Docker CE Stable - x86_64
    epel                                         Extra Packages for Enterprise Linux 8 - x86_64
    extras                                       Rocky Linux 8 - Extras
    powertools                                   Rocky Linux 8 - PowerTools
    
    Shell > dnf config-manager --disable powertools 

    永久开启某一个已经被关闭的存储库:

    Shell > dnf config-manager --enable powertools

存储库配置文件说明

所有存储库的配置文件都存放在 /etc/yum.repos.d/ 目录中并以 .repo 结尾,每个 .repo 文件可以包含一个或一组存储库,使用者可以根据情况选择性地启用或关闭:

Shell > ls -l /etc/yum.repos.d/
total 72
-rw-r--r--  1 root root 1919 Sep 13  2024 docker-ce.repo
-rw-r--r--  1 root root 1680 Aug 31  2024 epel-modular.repo
-rw-r--r--  1 root root 1332 Aug 31  2024 epel.repo
-rw-r--r--  1 root root 1779 Aug 31  2024 epel-testing-modular.repo
-rw-r--r--  1 root root 1431 Aug 31  2024 epel-testing.repo
-rw-r--r--. 1 root root  710 Jun  7  2024 Rocky-AppStream.repo
-rw-r--r--. 1 root root  695 Jun  7  2024 Rocky-BaseOS.repo
-rw-r--r--  1 root root 1773 Jun  7  2024 Rocky-Debuginfo.repo
-rw-r--r--. 1 root root  360 Jul 11  2024 Rocky-Devel.repo
-rw-r--r--. 1 root root  695 Jun  7  2024 Rocky-Extras.repo
-rw-r--r--. 1 root root  731 Jun  7  2024 Rocky-HighAvailability.repo
-rw-r--r--. 1 root root  680 Jun  7  2024 Rocky-Media.repo
-rw-r--r--. 1 root root  680 Jun  7  2024 Rocky-NFV.repo
-rw-r--r--. 1 root root  690 Jun  7  2024 Rocky-Plus.repo
-rw-r--r--. 1 root root  715 Mar 29 17:39 Rocky-PowerTools.repo
-rw-r--r--. 1 root root  746 Jun  7  2024 Rocky-ResilientStorage.repo
-rw-r--r--. 1 root root  681 Jun  7  2024 Rocky-RT.repo
-rw-r--r--  1 root root 2335 Jun  7  2024 Rocky-Sources.repo

Shell > cat /etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
...

Shell > cat /etc/yum.repos.d/Rocky-AppStream.repo
[appstream]
name=Rocky Linux $releasever - AppStream
mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=AppStream-$releasever
#baseurl=http://dl.rockylinux.org/$contentdir/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
countme=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial

文件内容说明如下:

  • 使用 "[ ]" 包含存储库的标识名 ID
  • "name" 表示存储库的名称
  • "baseurl" 表示存储库的路径,支持多种协议,如 https、http、ftp、file 、NFS等,URL 中的 "$" 表示相关的存储库变量
  • "mirrorlist" 表示镜像存储库列表
  • "#" 开头表示是注释行
  • "gpgcheck" 表示是否对存储库中的软件包开启 gpg 签名检查,以防止软件包被人恶意篡改。非对称加密的内容我们介绍 Git 的时候说到了
  • "enabled" 表示是否启用该存储库
  • "gpgkey" 表示密钥(key)的位置,这里的密钥即公钥

其他未说明的内容参阅 man 5 yum.conf

搭建本地的存储库

文件存放的介质可以是 DVD 光盘,也可以是 .iso 光盘镜像文件。若选择的是 .iso 镜像文件,我们建议您最好选择包含所有存储库软件包的那个最大文件。

file 协议

演示环境下将当前活跃的存储库全部永久关闭:

Shell > dnf repolist
repo id                                      repo name
appstream                                    Rocky Linux 8 - AppStream
baseos                                       Rocky Linux 8 - BaseOS
docker-ce-stable                             Docker CE Stable - x86_64
epel                                         Extra Packages for Enterprise Linux 8 - x86_64
extras                                       Rocky Linux 8 - Extras
powertools                                   Rocky Linux 8 - PowerTools

Shell > dnf config-manager --disable appstream baseos docker-ce-stable epel extras powertools   
# 假设您往当前的服务器上传了 .iso 文件

# 创建镜像的保存位置
Shell > mkdir /usr/local/src/DVD-iso
Shell > mv Rocky-8.10-x86_64-dvd1.iso /usr/local/src/DVD-iso/

# 非永久性地临时挂载
Shell > mount /usr/local/src/DVD-iso/Rocky-8.10-x86_64-dvd1.iso /mnt/

Shell > mount | grep -i iso
/usr/local/src/DVD-iso/Rocky-8.10-x86_64-dvd1.iso on /mnt type iso9660 (ro,relatime,nojoliet,check=s,map=n,blocksize=2048)

Shell > df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
...
/dev/loop0     iso9660    14G   14G     0 100% /mnt

# 创建 repo 文件
Shell > cd /etc/yum.repos.d/ && touch my-local.repo

# 文件内容如下:
## "file://" 代表协议,"/mnt/AppStream/" 表示对应存储库的目录
## 请注意存储库 ID 必须是唯一的
Shell > cat /etc/yum.repos.d/my-local.repo
[local-appstream]
name = Rocky Linux $releasever Appstream
baseurl = file:///mnt/AppStream/
enabled=1
gpgcheck=0

# 生成缓存,完成
## 按照这种方法再依次添加 baseos、powertools 等存储库
Shell > dnf makecache

Shell > dnf repolist
repo id                                                 repo name
local-appstream                                         Rocky Linux 8 Appstream

恢复到之前的存储库:

Shell > rm -rf /etc/yum.repos.d/my-local.repo

Shell > dnf config-manager --enable appstream baseos docker-ce-stable epel extras powertools

Shell > umount /mnt

ftp 协议

FTP 协议的配置方法也差不多,需要首先在局域网内创建一个可供所有人读取和下载的公共 FTP 服务器(注意 FTP 服务的权限以及相关目录的权限),然后配置相关的 baseurl 即可。见如下操作:

# 我使用的是 VSFTP
Shell > dnf -y install vsftpd

Shell > dnf config-manager --disable appstream baseos docker-ce-stable epel extras powertools

# 可供所有人读取和下载的 FTP 服务器,即 FTP 服务器允许匿名用户访问与下载,但不允许匿名用户创建目录和上传文件
## 查看 VSFTP 的默认配置
Shell > grep -v -E "^$|^#" /etc/vsftpd/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES

# 关闭本地用户;开启匿名用户
Shell > grep -v -E "^$|^#" /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
...
local_enable=NO
...

## 进行挂载
Shell > mount /usr/local/src/DVD-iso/Rocky-8.10-x86_64-dvd1.iso /mnt/

# 匿名用户的 FTP 根目录为 /var/ftp/ ,默认在根下会有一个 pub 目录
## 将我们 iso 镜像文件里面的文件全部递归复制到 pub 目录
## 文件挺大,复制需要花费挺长时间
Shell > cp -r /mnt/* /var/ftp/pub/

Shell > du -sh /var/ftp/pub/
14G     /var/ftp/pub/

# 启用 VSFTP 服务
Shell > systemctl start vsftpd.service

Shell > cd /etc/yum.repos.d/ && touch ftp.repo

# 写入的文件如下:
Shell > cat /etc/yum.repos.d/ftp.repo
[ftp-local-appstream]
name = Rocky Linux $releasever Appstream
baseurl = ftp://192.168.100.20/pub/AppStream/
enabled=1
gpgcheck=0

# 配置成功
## 若还有其他机器需要指向相应的 ftp 存储库,完成相应配置即可
Shell > dnf clean all && dnf makecache 
Shell > dnf repolist
repo id                                                   repo name
ftp-local-appstream                                       Rocky Linux 8 Appstream

恢复到之前的存储库:

Shell > umount /mnt

Shell > rm -rf /etc/yum.repos.d/ftp.repo

Shell > systemctl stop vsftpd.service

Shell > rm -rf /var/ftp/pub/*

Shell > dnf config-manager --enable appstream baseos docker-ce-stable epel extras powertools
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇