包管理的作用是管理整个系统环境中的所有软件包。支持从远程仓库下载、安装并自动处理依赖。
deepin 是基于 Debian 的 Linux 发行版,因此使用 apt 作为包管理器,dpkg 作为包管理器基础,两者都作为系统的一部分被预装在操作系统环境中。
软件包管理相关的概念解释。
软件包可以看作整个系统的组成单元,操作系统由若干软件包和文件组成。在 deepin 或其他基于Debian的发行版中,软件包的后缀名为.deb
。当在系统中安装某软件包时,需要先补齐该软件包所需的依赖,否则软件包将不允许被安装。
软件包的唯一标识,一般情况下,相同包名的软件包不允许在系统中安装多个,即使版本不同。
安装软件包时所需要的其他软件包称为该软件包的依赖。通常来说,依赖可能是运行库,也可能是资源包等,依赖将由打包者决定。同时依赖可以设置版本作为可选条件,若系统中存在的依赖软件包版本与所需软件包版本要求不符,则视为该依赖包不满足。
依赖地狱:当软件包的依赖树过于复杂时,系统可能无法同时满足所有软件的依赖需求,此时我们可以将这种现象称为依赖地狱。举个简单的例子:软件包A依赖于1.0版本的软件包C,软件包B依赖于2.0版本的软件包C,此时软件包A和软件包C的1.0版本已经被安装,此时若想要安装软件包B,则需将软件包C的版本升级至2.0,但若这么做便导致软件包A的依赖无法被满足。
现代的软件包管理器支持自动从远程的软件包仓库中下载软件包及其依赖,这一定程度上无需我们自己考虑软件的依赖问题。而我们只需要考虑从哪些软件仓库获取所需的包即可,这些仓库通常由发行版所维护,仓库中的软件包通常能保证可用的依赖关系。
发行版所提供的仓库可能由于地理位置或网络环境等因素导致访问速度慢甚至无法访问,因此有些团队或组织会针对某些发行版所维护的软件仓库提供镜像仓库,镜像仓库的内容应当与发行版所维护的内容一致,但用于镜像仓库同步仓库内容需要时间,因此常常会出现镜像仓库的更新略有延迟的情况,但这种情况通常只会有短暂的影响。
介绍 apt 软件包管理的基本用法。
apt 支持安装本地软件包,也支持从远程仓库自动下载软件包。
要安装一个本地的软件包,可以使用如下命令:
sudo apt install 包文件名
这个操作会自动从远程仓库中查找所需要的依赖,并同时安装到系统中。
这里需要注意的是,包文件名必须是一个路径,可以是相对路径也可以是绝对路径,即使包文件就在当前目录下,也必须写成
./包文件名
的格式。
要根据包名从远程仓库安装软件包,可以使用如下命令:
sudo apt install 包名
假设要安装gimp这款图像处理软件,包名就是gimp
。
deepin/UOS 应用商店的规范要求应用的包名需要是域名倒置的格式,因此,gimp在应用商店仓库中的包名为:
org.gimp
。实际情况中,两者都可以成功安装gimp。这两者存在于不同的仓库中,gimp
来自 Debian 上游的打包,而org.gimp
则来自 deepin 商店团队的打包。
想要删除一个已经安装成功的软件包,可以使用两个命令,通常来说可以使用:
sudo apt remove 包名
但这个操作不会删除软件的配置文件,想要同时删除配置文件,可以使用:
sudo apt purge 包名
若系统中存在作为某些软件包的依赖而自动安装的软件包,但是由于软件包的删除或更新导致这些软件包不再被需要,此时可以使用如下命令自动发现并卸载他们
sudo apt autoremove
也可以将第一种删除命令和autoremove合在一起执行:
sudo apt autoremove 包名
指的是卸载指定包名的软件包并清除不再被需要的软件包。
前边提到了 apt 可以从远程仓库搜索和下载软件包,其机制是在某一时刻从远程仓库获取仓库中所有软件包的列表,并在需要的时候读取本地的列表文件。这个列表中描述了软件仓库中存在哪些软件包,以及其基本信息如版本号、依赖列表、作者等。因此,当我们需要从远程仓库获取软件包之前,需要先更新本地缓存,以保证本地的软件包列表与远程仓库中的列表保持一致:
sudo apt update
该操作会将远程仓库信息缓存到/var/lib/apt/lists
中。
若发行版或其他软件源发布更新,远程仓库中的部分软件包将会变更到新版本,此时若在本机使用sudo apt update
命令更新缓存后,apt将会发现这种变化并通知用户有软件需要升级,此时可以使用如下命令进行升级:
sudo apt upgrade
若需要通过关键字搜索软件包,可使用:
sudo apt search 关键字
该命令将列出所有搜索到的软件包和他们的部分信息。
从本地缓存中根据包名列出所有符合条件的软件包,包名部分支持通配符:
sudo apt list 包名
该命令将列出所有符合条件的软件包信息,若系统中已经安装,则会有[已安装]
字样。
除了上边列出的方法外,Debian 还提供了根据文件名或路径搜索软件包的功能,使用该功能需要安装软件包apt-file
。
安装完成后需要先执行:
sudo apt-file update
之后就可以使用如下命令搜索软件包:
sudo apt-file search 文件名或路径
这里的参数是文件名或路径。实际上该操作仅仅是模糊匹配文件的完整路径,你只需要提供路径中的任何一部分或者全部即可。
安装
apt-file
功能后,会令apt在执行update命令时下载额外的缓存,该缓存是软件包名和其中文件名的列表,apt就是根据这部分缓存执行的操作。该功能带来的后果是apt在执行update命令时会消耗更多的时间和网络流量。
dpkg作为包管理器的底层部分,通常情况下并不推荐日常使用。因为它并不能自动处理依赖关系,也不支持从远程仓库获取软件包。
安装本地软件包,需要使用-i
选项:
sudo dpkg -i 软件包文件名
这里无需像apt一样必须提供一个路径,若包文件就在当前目录,可直接输入文件名即可。
可以使用-r
或-P
选项,这两者可类比apt的remove
命令和purge
命令。
sudo dpkg -r 包名
或
sudo dpkg -P 包名
其中后者会同时删除配置文件。
系统中的文件可能所属于某个软件包,当软件包被卸载时将此类文件将被删除,要查看此类文件所对应的软件包,可使用-S
选项:
sudo dpkg -S 文件名
出于某种需要,你可能需要构建一个软件包,本章将引导你制作一个简单的软件包。该软件包将为你安装一个hello命令,当你在终端输入hello时,他将显示hi 你的用户名
。
需要安装包:fakeroot
sudo apt install fakeroot
工作目录中用于存储包的所有内容,包括包的描述文件、内容文件等。
我们需要建立一个空的目录,并且切换到该目录下:
mkdir mypkg
cd mypkg
在打包规范中规定,包工作目录根目录的文件在安装时将被部署到系统根目录的对应目录中。例如:在mypkg/usr/bin
中新建一个hello文件,那么安装此包时,该文件将被部署到/usr/bin
目录下。
现在我们需要建立mypkg/usr/bin
文件夹并在其中创建一个空文件名为hello
:
mkdir usr/bin -p
touch usr/share/hello
此后我们需要编辑此文件,你可以直接在文件管理器中使用文本编辑器打开,若你熟悉vim的命令行编辑器,也可以使用他们。你需要在该文件中输入以下内容:
#!/bin/bash
echo hi ${USER}
并使用以下命令为其添加可执行权限,也可右键->属性->打开可执行权限。
chmod +x usr/bin/hello
在工作目录中,DEBIAN
目录专用于存储描述整个软件包的文件,以及一些脚本文件。在这里,必须要存在的是control
文件,该文件中将规定包名、版本、打包者信息、依赖等信息。
因此,我们需要创建DEBIAN
目录和control
文件:
mkdir DEBIAN
touch control
然后编辑control
文件,在其中输入以下内容:
Package: myhello
Maintainer: MySelf
Architecture: all
Version: 1.0
Depends: bash
Description: 自制软件包,提供hello命令。
至此,您的工作目录应当为如下结构:
mypkg
├── DEBIAN
│ └── control
└── usr
└── bin
└── hello
一切准备就绪,开始打包!
cd ..
fakeroot dpkg -b mypkg
此后,若一切顺利,你的当前目录下将会生成一个名为mypkg.deb
的文件,该文件就是构建成功的软件包。
你可以使用如下命令安装此软件包:
sudo dpkg -i mypkg.deb
假设你的用户名为myname
,则你在终端输入hello
后回车,便会显示hi myname
。