Alpine 软件包管理器

来自 Alpine Linux
(重定向自 软件包管理)

本页面介绍了 Alpine 软件包管理器 (APK),Alpine Linux 中的软件包管理器。如需快速入门,请参阅 Working with APK。无盘模式下的软件包管理需要额外的步骤,涉及 Alpine Local Backup Utility (lbu)

概述

apk-tools 提供了 apk,它支持以下操作:

add 添加新软件包或将软件包升级到正在运行的系统
del 从正在运行的系统中删除软件包
fix 修复软件包或系统
update 更新可用软件包的索引
info 打印有关已安装或可用软件包的信息
search 使用通配符模式搜索软件包或描述
upgrade 升级当前已安装的软件包
cache 本地缓存软件包仓库的维护操作
version 比较已安装和可用软件包之间的版本差异
index 从软件包列表创建仓库索引
fetch 下载(但不安装)软件包
audit 列出从初始软件包安装状态到文件系统的更改
verify 验证软件包签名
dot 为给定软件包创建 graphviz 图形描述
policy 显示更新给定软件包的仓库,以及也提供该软件包的仓库
stats 显示统计信息,包括已安装和可用软件包的数量、目录和文件数量等。
manifest 显示给定软件包中包含文件的校验和

软件包与仓库

Alpine Linux 的软件包是经过数字签名的 tar.gz 压缩包,包含程序、配置文件和依赖关系元数据。它们的扩展名为 .apk,通常被称为 “a-packs”。Alpine Linux 中的软件包被组织到三个官方仓库中。从技术上讲,任何包含 *.apk 文件集合以及名为 APKINDEX.tar.gz 的特殊索引文件的目录都可以被视为仓库,尽管是个人仓库。Pinned Repositories 可以用于阻止特定版本的软件包升级。

子软件包

在 Alpine Linux 中,二进制软件包被精简并拆分为子软件包,以便更好地控制安装的功能,并尽可能保持安装的精简和高效。

World

/etc/apk/world 中,apk 维护着 world,即软件包选择需要满足的约束列表。World 描述了期望的系统状态。命令 apk add fooapk del bar 通过在 /etc/apk/world 中添加 foo 或 bar 作为依赖约束来操作期望的状态。

/etc/apk/world 是一个纯文本文件,每行一个使用依赖关系表示法的约束。每行的格式为:name{@tag}{[<>~=]version}

为了使系统被认为是正确的,此处列出的每个约束都必须是可解决的,并且不得提交任何不正确的事务。如果它无法验证请求更改的正确性,它将在尝试更改系统上实际安装的软件包之前撤回添加约束。因此,apk 永远不会提交导致系统无法启动的更改。

如果手动编辑 /etc/apk/world,请运行 apk fix 以将已安装的软件包与期望的系统状态同步。软件包的安装或删除是修改此系统状态的副作用。

apk fix

更新软件包列表

随着软件包的添加和升级,Alpine Linux 仓库会发生变化。要获取最新的可用软件包列表,请使用 update 命令。该命令从每个仓库下载 APKINDEX.tar.gz 并将其存储在本地缓存中,通常是 /var/cache/apk//var/lib/apk//etc/apk/cache/

apk update

--update-cache 或简写 -U 开关添加到另一个 apk 命令,例如 apk --update-cache upgradeapk -U add ...,该命令的效果与在其他 apk 命令之前首先运行 apk update 相同。

最好始终在执行 upgrade 或 add 命令之前执行 update。这样,命令将从仓库安装最新的可用软件包。

添加软件包

使用 add仓库安装软件包。任何必要的依赖关系也会被安装。如果您有多个仓库,add 命令将安装最新的软件包。

apk add openssh apk add openssh openntp vim

可以通过向软件包添加标签来安装来自pinned repositories 的软件包。

apk add wireguard-go@testing

.

添加本地软件包

要安装本地可用的 apk 软件包,例如,如果此设备没有互联网访问权限,但您可以直接将 apk 软件包上传到该设备,请使用 --allow-untrusted 标志。

apk add --allow-untrusted /path/to/file.apk

请注意,可以指定多个软件包。安装本地软件包时,还应指定所有依赖项。例如

apk add --allow-untrusted /var/tig-2.2-r0.apk /var/git-2.11.1-20.apk

移除软件包

使用 del 删除软件包(以及不再需要的依赖项)。

apk del openssh apk del openssh openntp vim

升级正在运行的系统

要获取当前正在运行的系统的已安装release branch 的最新安全升级和错误修复,需要两个步骤:

  • update 可用软件包列表
  • upgrade 已安装的软件包

apk update apk upgrade

或者,将相同的操作合并为一个命令:

apk -U upgrade

这是一个示例,展示了在具有repositories pinned 的系统上的过程。

 # apk update
 fetch https://dl-3.alpinelinux.org/alpine/v3.6/main/x86_64/APKINDEX.tar.gz
 fetch https://dl-3.alpinelinux.org/alpine/v3.6/community/x86_64/APKINDEX.tar.gz
 fetch https://dl-3.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz
 v3.6.2-191-gf98d79930f [https://dl-3.alpinelinux.org/alpine/v3.6/main]
 v3.6.2-190-ga5d68c47df [https://dl-3.alpinelinux.org/alpine/v3.6/community]
 v3.6.0-4624-g11f1b9c8ab [https://dl-3.alpinelinux.org/alpine/edge/testing]
 OK: 20118 distinct packages available
 
 # apk upgrade
 (1/2) Upgrading extra-cmake-modules@testing (5.38.0-r0 -> 5.39.0-r0)
 (2/2) Upgrading extra-cmake-modules-doc@testing (5.38.0-r0 -> 5.39.0-r0)
 Executing mdocml-apropos-1.14.1-r0.trigger
 OK: 2635 MiB in 803 packages

要仅升级特定软件包,请使用 upgrade 命令并指定它们。

apk update apk upgrade busybox

要启用软件包的无人值守自动升级,请参阅 apk-autoupdate 软件包。请参阅 Upgrading Alpine 以将 Alpine Linux 升级到较新的 release branch

升级 “无盘” 和 “数据” 磁盘模式安装

对于升级 无盘Data disk 模式安装,升级正在运行的系统需要一些额外的步骤

搜索软件包

search 命令在仓库索引文件中搜索可安装的软件包。

返回格式为 软件包-版本。对于 apk add 软件包,请省略版本

示例

  • 列出所有可用的软件包及其描述

    apk search -v

  • 列出属于 ACF 系统的所有软件包

    apk search -v 'acf*'

  • 要列出所有在其描述中包含 NTP 的软件包,请使用 -d--description 选项。

    apk search -v --description 'NTP'

  • 列出所有提供 git 命令的软件包

    apk search -v 'cmd:git'

软件包信息

info 命令提供有关软件包内容、其依赖关系以及哪些文件属于软件包的信息。

对于给定的软件包,可以选择每个元素(例如,-w 仅显示网页信息),或者使用 -a 命令显示所有信息。

示例

apk info -a zlib

zlib-1.2.5-r1 description:
A compression/decompression Library

zlib-1.2.5-r1 webpage:
https://zlib.net

zlib-1.2.5-r1 installed size:
94208

zlib-1.2.5-r1 depends on:
libc0.9.32

zlib-1.2.5-r1 is required by:
libcrypto1.0-1.0.0-r0
apk-tools-2.0.2-r4
openssh-client-5.4_p1-r2
openssh-5.4_p1-r2
libssl1.0-1.0.0-r0
freeswitch-1.0.6-r6
atop-1.25-r0 

zlib-1.2.5-r1 contains:
lib/libz.so.1.2.5
lib/libz.so.1
lib/libz.so 

zlib-1.2.5-r1 triggers:

如示例所示,您可以确定:

  • 软件包的描述-d--description
  • 应用程序托管的网页-w--webpage
  • 软件包安装后将需要的空间大小(以字节为单位)(-s--size
  • 使用此软件包所需的软件包(depends)(-R--depends
  • 需要安装此软件包的软件包(required by)(-r--rdepends
  • 软件包的内容,即它安装的文件(-L--contents
  • 此软件包设置的任何 triggers。(-t--triggers)此处列出的是被监视的目录;如果目录发生更改,则在 apk add/delete 结束时运行触发器脚本。例如,在安装所有添加内核模块的软件包后执行一次 depmod。

检查文件所有权

info 命令也用于确定文件属于哪个软件包。例如

apk info --who-owns /sbin/lbu

将显示

/sbin/lbu is owned by alpine-conf-x.x-rx

检查依赖关系

下面解释了用于检查软件包依赖关系和反向依赖关系的 info 命令。

-R--depends 选项列出软件包的依赖项。

apk info --depends pipewire

pipewire-1.0.6-r1 depends on:
/bin/sh
so:libc.musl-x86_64.so.1
so:libpipewire-0.3.so.0

-r--rdepends 选项列出软件包的反向依赖项(所有其他依赖于该软件包的软件包)。

apk info --rdepends pipewire

pipewire-1.0.6-r1 is required by:
xdg-desktop-portal-wlr-0.7.1-r0
pipewire-pulse-1.0.6-r1

列出已安装的软件包

要列出所有已安装的软件包,请使用:

apk info

要按字母顺序列出所有已安装的软件包,并附带每个软件包的描述,请执行:

apk -vv info

apk 工具没有子命令来列出手动安装的且没有反向依赖关系的软件包。要在不使用 lbu 的传统系统上获取此信息,请尝试此脚本。请注意,这种方法也会列出像 alpine-base 这样的不应删除的核心软件包。

#!/bin/sh
apk info | grep -ve '-doc$' | sort | while read pkg
        do
                rdep=`apk info -qr "$pkg"`
                [ -z "$rdep" ] && echo $pkg
        done

apk dot

dot 选项将软件包依赖关系呈现为 graphviz 图形。下面记录了使用 dot 选项的步骤。

将 apk dot 选项的输出保存到 dot 文件。

$ apk dot seatd > seatd_dependencies.dot

使用 Graphviz 将 dot 文件转换为图形格式,例如 PNG、PDF 或 SVG。

$ dot -Tpng seatd_dependencies.dot -o seatd_dependencies.png
Seatd dependencies
Seatd 依赖关系

apk policy

要显示软件包的安装来源仓库和更新来源仓库,以及任何标记或启用的仓库(如果存在),其中也为该架构提供了该软件包 - 即其策略

apk policy package

例如

 $ apk policy vlc
 vlc policy:
  2.2.6-r1:
    lib/apk/db/installed
    https://dl-3.alpinelinux.org/alpine/v3.7/community
  3.0.0_rc2-r1:
    @edgecommunity https://dl-3.alpinelinux.org/alpine/edge/community

本地缓存

APK 可以在本地磁盘上保留已安装软件包的缓存。HDD 或 sys 模式安装不需要 apk 缓存,但它仍然允许通过网络提供软件包,例如,供其他本地计算机安装。

注意: 对于 无盘 安装,需要本地软件包缓存才能在启动时自动(重新)安装软件包。

随着时间的推移,当较新的软件包被添加到缓存中时,软件包的旧版本默认保留在缓存目录中。可以使用 clean 命令删除软件包的旧版本。

apk cache clean

或者要查看删除了什么,请包含 verbose 开关。

apk -v cache clean

如果软件包意外地从缓存目录中删除,请使用 download 命令:

apk cache download

上述两个步骤可以使用 sync 命令合并为一个 - 这会清除旧软件包并下载丢失的软件包。

apk cache -v sync

APK 高级用法

命令行仓库选项

默认情况下,apk 实用程序将使用系统仓库进行所有操作。可以通过以下选项覆盖此行为:

--repositories-file REPOFILE 通过指定仓库文件来覆盖系统仓库。
-X|--repository REPO 指定一个补充仓库,该仓库将与系统仓库一起使用。此选项可以多次提供。

apk add cherokee --update-cache --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted

阻止特定软件包升级

在某些情况下,您可能想要升级系统,但将特定软件包保持在较低级别。可以添加 “粘性” 或版本化的依赖关系。例如,要将 asterisk 软件包保持在 1.6.2 或更低级别:

apk add asterisk=1.6.0.21-r0

apk add 'asterisk<1.6.1'

之后,执行

apk upgrade

将升级整个系统,同时将 asterisk 软件包保持在 1.6.0 或更低级别。

要稍后升级到当前版本,

apk add 'asterisk>1.6.1'

将确保使用 1.6.1 作为最低版本。

您还可以使用 “模糊” 版本匹配将版本固定到主版本/次要版本。例如

apk add 'asterisk=~1.6'

将匹配任何以 1.6 开头的 asterisk 版本(例如 1.6.0.21-r0 或 1.6.9.31-r9)。

如果您希望通过软件包固定来实现确定性的、可重复的软件包安装(例如在容器化环境中),则了解您的软件包仓库的版本保留规则非常重要。始终固定到旨在用于您的 release branch 的软件包版本。在 edge branch 上固定到某个版本可能会在软件包版本从仓库中撤销后停止工作。

Commit 钩子

如果您想在 apk 每次提交时触发操作或运行特定脚本,则有一种内置方法可以实现这一点。在每次提交时,apk 都会查找位于 “/etc/apk/commit_hooks.d/” 目录中的可执行文件,并在提交之前和之后执行它们。为了提供一种在 apk 提交更改之前或之后选择性地运行钩子的方法,脚本以 “pre-commit” 或 “post-commit” 作为参数 1 调用。这是一个在提交前后执行不同操作的钩子示例:

#!/bin/sh if [ "$1" = "pre-commit" ]; then do_something elif [ "$1" = "post-commit" ]; then do_something_else fi

Commit 钩子是 $PATH 感知的,因此为了安全起见,建议指定可执行文件的绝对路径。

Rosetta Stone

Rosetta Stone 或比较图表显示了与软件包管理相关的标准操作在 Alpine Linux 中与其他流行的发行版相比是如何完成的。

故障排除

错误:无法选择软件包

此错误通常表示软件包管理器找不到合适的软件包进行安装。在发出添加软件包的命令时,例如:apk add labwc,您可能会收到以下错误消息:

ERROR: unable to select packages:
 labwc (no such package):
 required by: world[labwc]

上述错误表示 labwc仓库中不存在,该仓库当前配置在 /etc/apk/repositories 中。确保 community 仓库已启用,因为默认情况下仅启用 main 仓库。您可能还需要检查 软件包数据库以确定正确的软件包名称以及软件包可用的仓库

错误:无法满足的约束

此错误表示依赖关系冲突。这意味着您尝试安装的软件包具有无法在当前软件包仓库中同时满足的依赖关系。

您可能需要检查 软件包数据库以确定正确的软件包名称和版本以及软件包可用的仓库

警告:此 apk-tools 版本过旧!

apk updateapk upgradeapk add 可能会报告以下内容:

WARNING: This apk-tools is OLD! Some packages might not function properly

如果您正在运行 Alpine Linux 稳定版本,并且还安装了某些 edge/main、edge/community 或 testing 软件包,则可能会发生这种情况。一种解决方案是考虑升级 apk-tools。如果 edge 已经在您的仓库中被标记,请尝试:

apk add --upgrade apk-tools@edge

错误:不可信的签名

当 release 版本更改时,会发生这种情况。您需要更新本地 apk 密钥。

如果您已经更新了仓库,请允许它们在没有可信密钥的情况下更新。

apk update --allow-untrusted

然后安装密钥升级。

apk fix --upgrade --allow-untrusted alpine-keys

现在更新和升级应该正常进行。

另一种选择是,可以在仓库更新之前,按照前面所述,直接获取、验证和安装更新后的 alpine-keys 软件包。

World 已更新,但以下软件包未被移除

在发出删除软件包的命令时,例如:apk del btrfs-progs,您可能会收到以下错误消息:

World updated, but the following packages are not removed due to:
  btrfs-progs: btrbk

在这里,删除软件包 btrfs-progs 会影响约束文件 /etc/apk/world 中的另一个软件包 btrbk。因此,软件包 btrfs-progs 将从约束文件中删除,但不会从系统中删除。btrfs-progs 将保留在系统中,直到依赖于 btrfs-progs 的约束(即 btrbk)被删除。

如果发出 apk del btrbk 命令,软件包 btrfs-progs 将自动从系统中删除,因为约束 btrfs-progs/etc/apk/world 中不存在。

参见

外部链接