pacman详解及常见问题

时间:2024-03-07 15:57:13

安装软件包:
软件包有很多可选依赖,是为软件提供额外功能, 安装软件时pacman 会输出可选依赖, 但不会在 pacman.log中,浏览安装软件的可选以来可用pacman -Si得到可选依赖的简短描述

 

安装指定的包:
安装或者升级单个软件包,或者一列软件包(包含依赖包)
    pacman -S package_name1 package_name2 ...

用正则表达式安装多个软件包:
    pacman -S $(pacman -Ssq package_regex)

 

有时候在不同的软件仓库中,一个软件包有多个版本(比如[extra]和[testing]):(就是指定包的精确位置)
    pacman -S extra/package_name

 

安装多个含有相似名称的软件包,而并非整个包组或全部匹配的软件包:
    pacman -S plasma-{desktop,mediacenter,nm}
  可以多层扩展,并不作限制:
    pacman -S plasma-{workspace{,-wallpapers},pa}

 

安装包组:
一些包属于一个可以同时安装的软件包组:
    pacman -S gnome
会提醒用户选择 gnome 内需要安装的包。

 

删除软件包:
删除单个软件包,保留其全部已经安装的依赖关系
    pacman -R package_name

删除指定软件包,及其所有没有被其他已安装软件包使用的依赖关系:
    pacman -Rs package_name

要删除软件包和所有依赖这个软件包的程序:
警告: 此操作是递归的,请小心检查,可能会一次删除大量的软件包。
    pacman -Rsc package_name

要删除软件包,但是不删除依赖这个软件包的其他程序:
    pacman -Rdd package_name

pacman删除某些程序时会备份重要配置文件,备份出来的文件是在其后面加上*.pacsave扩展名。
-n 选项可以避免备份这些文件:
    pacman -Rn package_name
注意: pacman 不会删除软件自己创建的文件(例如主目录中的 .dot 文件不会被删除。

 

升级软件包
警告: * 建议所有用户都 经常性的更新系统。Arch 只支持系统完整升级
一个 pacman 命令就可以升级整个系统。花费的时间取决于系统有多老。这个命令会同步非本地(local)软件仓库并升级系统的软件包:
    # pacman -Syu

 

查询包数据库:
-Q 参数查询本地软件包数据库:
    $ pacman -Q --help
-S 参数来查询远程同步的数据库:
    $ pacman -S --help
在包数据库中查询软件包,查询位置包含了软件包的名字和描述:
    $ pacman -Ss string1 string2 ...
-s的内置正则会匹配很多不需要的结果,所以应当指定仅搜索包名,而非描述或其他子段,下面的命令返回不必要结果:
    $ pacman -Ss \'^vim-\'
要查询已安装的软件包:
    $ pacman -Qs string1 string2 ...
按文件名查找软件库:
    $ pacman -Fs string1 string2 ...
显示软件包的详细信息:
    $ pacman -Si package_name
查询本地安装包的详细信息:
    $ pacman -Qi package_name
使用两个 -i 将同时显示备份文件和修改状态:
    $ pacman -Qii package_name
要获取已安装软件包所包含文件的列表:
    $ pacman -Ql package_name          #相当于centos中的rpm -ql+包名 命令
查询远程库中软件包包含的文件:
    $ pacman -Fl package_name          #相当于centos中的rpm -qpi+包名 命令

检查软件包安装的文件是否都存在,两个k将会更彻底的检查:
    $ pacman -Qk package_name

查询数据库获取某个文件属于哪个软件包:
    $ pacman -Qo /path/to/file_name

查询文件属于远程数据库中的哪个软件包:
    $ pacman -Fo /path/to/file_name

列出所有不再作为依赖的软件包(孤立orphans):
    $ pacman -Qdt

列出所有明确安装而且不被其它包依赖的软件包:
    $ pacman -Qet

显示软件包的依赖树:
    $ pactree package_name

检查一个安装的软件包被那些包依赖,可使用pkgtoolsAUR中的whoneeds:
    $ whoneeds package_name
  或者pactree中使用-r:
    $ pactree -r package_name


数据库结构:
pacman数据库通常位于 /var/lib/pacman/sync. 对于每一个在/etc/pacman.conf中指定的软件仓库, 这里都有一个一致的数据库。/var/lib/pacman/local数据库文件夹里每个tar.gz文件都包含着一个仓库的软件包信息。例如which 包:
      % tree which-2.20-6
      which-2.20-6
      |-- depends
      `-- desc
上面depends 项列出了该软件的依赖包, 而desc有该包的介绍,例如文件大小和MD5值 。


清理软件包缓存:
pacman 将下载的软件包保存在 /var/cache/pacman/pkg/ 并且不会自动移除旧的和未安装版本的软件包,因此需要手动清理,以免该文件夹过于庞大。
使用内建选项即可清除未安装软件包的缓存:
    # pacman -Sc

警告:

仅在确定当前安装的软件包足够稳定且不需要降级时才执行清理。pacman -Sc仅会保留软件包的当前有效版本,旧版本的软件包被清理后,只能从其他地方如 Arch Linux Archive (简体中文)中获取了。
pacman -Scc 可以清理所有缓存,但这样 pacman 在重装软件包时就只能重新下载了。除非空间不足,否则不应这么做。
由于以上种种局限,建议使用专门的脚本去处理清理哪些、清理多少缓存:
pacman 提供的 paccache 命令默认会删除近3个版本前的软件包
    # paccache -r
或者使用 pacman hooks 自动执行清理
也可以自己设置保留最近几个版本:
    # paccache -rk 1

清理所有未安装包的缓存文件:
    # paccache -ruk0

升级系统时安装其他软件包:

    # pacman -Syu package_name1 package_name2 ...

下载包而不安装它:
    # pacman -Sw package_name

安装一个本地包(不从源里下载):
    # pacman -U /path/to/package/package_name-version.pkg.tar.xz

要将本地包保存至缓存,可执行:
    # pacman -U file://path/to/package/package_name-version.pkg.tar.xz

安装一个远程包(不在 pacman 配置的源里面):
    # pacman -U http://www.example.com/repo/example.pkg.tar.xz

 

要禁用 -S, -U 和 -R 动作,可以使用 -p 选项.
pacman 会列出需要安装和删除的软件,并在执行动作前要求需要的权限。

 

安装原因:
pacman数据库按照软件包被安装的原因,将其分为两类:
  1、指定安装包:通过pacman-S或者-U指令安装的软件包。
  2、依赖包:指定安装包所依赖的软件包,尽管命令中未传入,但仍然会被安装。

 

当安装软件包时,可以把安装原因指定设为依赖:
    # pacman -S --asdeps package_name

但是当重新安装该软件包时,安装原因将会被设为软件包所默认的。 指定安装的软件包列表可用pacman -Qe, 已安装的依赖包可用pacman -Qd获取。 改变某个已安装软件包的安装原因,可以执行:
    # pacman -D --asdeps package_name
使用--asexplicit改为指定安装。

查询一个包含具体文件的包名
同步文件数据库:
    # pacman -Fy
查询包含某个文件的包名,比如:
    # pacman -Fs pacman
      core/pacman 5.0.1-4
      usr/bin/pacman
      usr/share/bash-completion/completions/pacman
      extra/xscreensaver 5.36-1
      usr/lib/xscreensaver/pacman
提示: 可以设置一个 crontab 或者 systemd timer 来定期同步文件信息数据库。

 

配置:
pacman 的配置文件位于/etc/pacman.conf。

通用选项
通用选项都在[options]段。阅读 man 手册或者查看默认的 pacman.conf 可以获得有关信息和用法。

升级前对比版本
要查看旧版和新版的有效安装包,取消/etc/pacman.conf中"VerbosePkgLists"的注释即可。
修改后的pacman -Syu输出如下:

Package (6) Old Version New Version Net Change Download Size
extra/libmariadbclient 10.1.9-4 10.1.10-1 0.03 MiB 4.35 MiB
extra/libpng 1.6.19-1 1.6.20-1 0.00 MiB 0.23 MiB
extra/mariadb 10.1.9-4 10.1.10-1 0.26 MiB 13.80 MiB

Pacman 具有颜色选项,在/etc/pacman.conf文件中取消 "Color" 的注释行即可.

不升级软件包
如果由于某种原因,用户不希望升级某个软件包,可以加入内容如下:
    IgnorePkg = 软件包名

 

多软件包可以用空格隔开,如果只打算忽略一次升级,可以使用 --ignore 选项。
忽略了的软件包可通过 pacman -S 升级
不升级软件包组:
    IgnoreGroup = gnome

跳过软件包文件
Warning: 跳过软件包时请考虑清楚,Arch 官方并不支持 部分更新。
要跳过某些文件夹的安装,可以将它们放到 NoExtract 中,例如不想安装 systemd unit 文件:
    NoExtract=usr/lib/systemd/system/*


软件仓库
除了特殊的options section, 每个pacman.conf中的section都定义了一个使用的软件包仓库,仓库是多个软件包的逻辑上的集合,他们物理上存储在一个或多个服务器:这也是为什么每一个服务器都叫做这个仓库的镜像。

 

仓库区分为:官方与非官方两类。
配置文件中仓库的顺序十分重要,当几个仓库出现同名安装包,不管版本号是否相同,pacman将使用配置文件中排前的仓库。upgrade升级整个系统来让新添加的仓库生效。
每个仓库设置都可以直接指定镜像列表或者Include引用其他的文件:例如,官方镜像引用了/etc/pacman.d/mirrorlist/

 

软件包的安全性
pacman 4 支持软件包签名。语句 SigLevel = Required DatabaseOptional 将启用全局签名验证,但会被每个软件仓库的 SigLevel 行所覆盖。

小心使用 --force(强制的意思)开关。使用不当会造成大问题。 如果 Arch 没有特殊声明要用,需慎重使用。

 

pacman 附带了许多实用工具能让系统使用更加便捷。所有工具功能都能通过 --help 开关查看:
    $ pacman -Ql pacman | awk -F"[/ ]" \'/\/usr\/bin/ {print $5}\'    来查看完整列表

 

常见问题:
升级时遇到的问题:
    error: could not prepare transaction
    error: failed to commit transaction (conflicting files)
    package: /path/to/file exists in filesystem
    Errors occurred, no packages were upgraded.
先用 pacman -Qo 文件的完整路径 检查哪个软件包提供了文件。如果不是其它软件包提供,将已经存在的文件重命名并重新升级。如果升级成功,可以删掉备份文件。

 

如果是通过 make install 等非 pacman 方式安装的软件,安装的文件不属于任何软件包!需要先手动删除这些文件即可正常安装软件。

 

每一个安装的软件包都会提供一个 /var/lib/pacman/local/$package-$version/files 文件,包含此软件包的元数据。如果文件损坏或者丢失将会导致升级时出现file exists in filesystem 错误。这种错误通常只会影响一个软件包,除了手动删除或移动所有的问题文件,可以作为特例使用pacman -S --force $package让 pacman 强制覆盖这些文件。
警告: --force 选项非常危险,建议在 Arch 新闻中明确通知的时候才使用它,否则可能导致系统无法启动。


"failed to commit transaction (invalid or corrupted package" 错误
看看/var/cache/pacman/pkg中是否有*.part结尾的文件,它们是没有完全下载的文件,删除它们并重新执行更新。这些程序一般是自定义的XferCommand 下载命令造成的。
# find /var/cache/pacman/pkg/ -iname "*.part" -exec rm {} \;


"error: failed to init transaction (unable to lock database)" 错误
pacman 在更新软件包数据库前,比如安装软件包时会创建一个文件锁 /var/lib/pacman/db.lck。该文件会阻止其他 pacman 实例在同一时间修改软件包数据库。如果 pacman 在更新数据库时收到干扰,旧锁会一直存在。

如果确认 pacman 没有在运行,那么删掉文件锁:
    # rm /var/lib/pacman/db.lck


安装时无法获取软件包
错误内容包含:Not found in sync db, Target not found 或 Failed retrieving file.
首先确认软件包确实存在(并注意错别字)。如果确认软件包存在,可能本地数据库过时了或者软件仓库没有配置好,试试 pacman -Syyu 强制数据库更新和升级。
也有可能包含该软件包的软件仓库没有启动。
例如,该软件包可能在 multilib 仓库里,但该仓库没有在 pacman.conf 中启用。

 

pacman 完全坏掉修复过程:
如果 pacman 完全坏掉不能使用,需要手动下载或构建需要的软件包(openssl, libarchive 和 pacman) 并解压到根目录。pacman 会和默认配置文件一起恢复。然后用 pacman 重新安装这些软件包以保证数据库的完整性。


pacman 更新时崩溃
如果 pacman 在删除、重新安装或更新软件包时 "数据库写入" 出错:
   1、从 Arch 安装媒体启动,最好用最新的安装媒体
   2、挂载根文件系统,通过 df -h 确认根文件目录包含足够的空间
   3、如果系统使用默认的数据库目录位置,可以通过root用户执行下面命令:
    # pacman --root=/mnt --cachedir=/mnt/var/cache/pacman/pkg -Syyu
  4、更新之后,可以通过下面命令确认是否还存在损坏的包:find /mnt/usr/lib -size 0
  5、通过下面命令重新安装依然损坏的软件包:
    #pacman --root /mnt --cachedir=/mnt/var/cache/pacman/pkg -S package.


升级系统重启后,出现"unable to find root device"错误,无法登陆
很有可能 initramfs 在内核升级时损坏,例如错误的使用 pacman 的 --force 选项。有两个选择:

Fallback 启动项
提示: 如果删除了此启动项,可以在启动时进入启动加载器的手动模式,将 initramfs 修改为 initramfs-linux-fallback.img 继续启动。

如果系统可以启动,运行如下命令可以生产原始内核 linux 的 initramfs:
# mkinitcpio -p linux

              待续..........

 

欢迎加入QQ群一起讨论Linux、开源等技术