Alpine Package Keeper

来自 Alpine Linux

本页面介绍了 Alpine Package Keeper (APK),Alpine Linux 中的软件包管理器。如需快速入门,请参阅APK 使用指南无盘模式下的软件包管理需要额外的步骤,涉及 Alpine 本地备份工具 (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 的特殊索引文件的目录都可以被视为仓库,尽管它可能是一个个人仓库。已固定的仓库可用于保留软件包的特定版本。

子软件包

在 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 update 再运行另一个 apk 命令相同。

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

添加软件包

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

apk add openssh apk add openssh openntp vim

可以通过向固定的仓库中的软件包添加标签来安装它们。

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

升级正在运行的系统

要获取当前安装的正在运行的系统的发行分支可用的最新安全升级和错误修复,需要两个步骤:

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

apk update apk upgrade

或者,将它们合并为一个命令:

apk -U upgrade

这是一个示例,显示了在具有固定仓库的系统上的操作步骤:

 # 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 软件包。请参阅升级 Alpine 以将 Alpine Linux 升级到更新的发行分支

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

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

搜索软件包

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)
  • 此软件包设置的任何触发器。(-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

要显示软件包的安装来源仓库和将从中更新的仓库,以及任何标记或启用的也提供该软件包的仓库(如果有),对于此架构 - 其 policy

apk policy 软件包

例如:

 $ 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)。

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

提交钩子

如果您希望在 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

提交钩子是 $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

错误:不受信任的签名

当发行版本更改时,会发生这种情况。您需要更新本地 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 中不存在。

参见

外部链接