Difference between revisions of "Pacman/Tips and tricks (简体中文)"

From ArchWiki
Jump to: navigation, search
(彩色输出)
(用 CacheClean 选择性的清空缓存: Pacman provide pacclean)
Line 77: Line 77:
 
==维护==
 
==维护==
 
保持系统干净,遵循 [[The Arch Way (简体中文)|Arch 之道]]。
 
保持系统干净,遵循 [[The Arch Way (简体中文)|Arch 之道]]。
 
===用 CacheClean 选择性的清空缓存===
 
[[CacheClean]] 是一个清理 {{ic|/var/cache/pacman/pkg}} 目录的 Python 脚本,可以指定保留几个软件包版本。<sup>[https://bbs.archlinux.org/viewtopic.php?id=9104]</sup>
 
 
[[AUR (简体中文)|AUR]] 提供了 {{AUR|Cacheclean}} 软件包。
 
  
 
===显示所有软件包及其大小===
 
===显示所有软件包及其大小===

Revision as of 09:05, 5 April 2013

概览 help replacing me
pacman的使用技巧。
相关内容
pacman (简体中文)
Mirrors (简体中文)
Creating Packages (简体中文)
Custom local repository (简体中文)
翻译状态: 本文是英文页面 Pacman_Tips翻译,最后翻译时间:2012-05-17,点击这里可以查看翻译后英文页面的改动。

修饰和便利

彩色输出

pacman 4.1.0 开始支持彩色输出,只需要在/etc/pacman.conf中取消 Color 行前面的注释即可使用。

快捷方式

使用命令别名简化常用pacman命令,方便使用和记忆。

配置 shell

下面是个范例,将其加入shell配置文件即,同时适用于BashZsh

# Pacman 别名示例
alias pacupg='sudo pacman -Syu'        # 同步软件仓库信息然后升级系统
alias pacin='sudo pacman -S'           # 从软件仓库安装软件包
alias pacins='sudo pacman -U'          # 从本地文件安装软件包
alias pacre='sudo pacman -R'           # 删除软件包,保留配置和依赖
alias pacrem='sudo pacman -Rns'        # 彻底删除软件包,清除配置,删除无用依赖
alias pacrep='pacman -Si'              # 显示软件仓库中某软件包的信息
alias pacreps='pacman -Ss'             # 在软件仓库搜索软件包
alias pacloc='pacman -Qi'              # 显示本地数据库中某软件包的信息
alias paclocs='pacman -Qs'             # 在本地数据库搜索软件包
# 更多示例
alias pacupd='sudo pacman -Sy && sudo abs'     # 同步软件仓库信息并更新abs
alias pacinsd='sudo pacman -S --asdeps'        # 将某软件包作为其它软件包的依赖安装
alias pacmir='sudo pacman -Syy'                # 强制刷新软件仓库信息

用法

就像使用普通命令一样使用这些别名即可。例如,要同步软件仓库信息然后升级系统:

$ pacupg

从软件仓库安装软件包:

$ pacin <软件包1> <软件包2> <软件包3>

安装软件包文件:

$ pacins /path/to/<软件包路径>

彻底删除软件包:

$ pacrem <软件包>

在软件仓库搜索软件包:

$ pacreps <关键字>

显示软件仓库中某软件包的信息(比如:占用空间,依赖关系):

$ pacrep <keywords>

注解

上面提供的只是一个例子。按照上面的格式,可以自己编写命令别名,比如:

alias pacrem='sudo pacman -Rns'
alias pacout='sudo pacman -Rns'

上面的例子中,pacrempacout代表同样的命令:sudo pacman -Rns。你可以使用自己喜欢的名称代替这些命令。

巧用 Bash 语法

下面应用Bash技巧,实现复杂的pacman功能。

  • 安装多个名称部分相同的软件包(而非安装整个软件包组),以kde为例:
 pacman -S kde-{applets,theme,tools}
  • 也可以嵌套使用:
 pacman -S kde-{ui-kde,kdeartwork}
  • 使用-s搜索时会匹配软件包描述,从而导致很多不需要的结果。限制只匹配软件包名称:
 pacman -Ss '^vim-'
  • pacman的-q操作会输出所有本地软件包名称。利用该输出、以及简单的shell技巧,重新安装所有名称包含“compiz”的软件包:
 pacman -S $(pacman -Qq | grep compiz)

维护

保持系统干净,遵循 Arch 之道

显示所有软件包及其大小

  • 将所有软件包按占用空间大小排序输出:
pacman -Qi | awk '/^Name/ {pkg=$3} /Size/ {print $4$5,pkg}' | sort -n
  • 使用 pacman-contrib 中的 pacsysclean
  • 安装 expac 并运行 expac -s "%-30n %m"
  • 用 [community] 中的 pacgraph 加 -c 选项可以生成所有安装的软件包及其大小.

查找不属于任何软件包的文件

建议定期检查 pacman 数据库之外的文件。通常这些文件是第三方程序使用一般方式安装 (例如 ./configure; make; make install)。下面脚本可以找出它们:

pacman-disowned
#!/bin/sh

tmp=${TMPDIR-/tmp}/pacman-disowned-$UID-$$
db=$tmp/db
fs=$tmp/fs

mkdir "$tmp"
trap  'rm -rf "$tmp"' EXIT

pacman -Qlq | sort -u > "$db"

find /bin /etc /lib /sbin /usr \
  ! -name lost+found \
  \( -type d -printf '%p/\n' -o -print \) | sort > "$fs"

comm -23 "$fs" "$db"

要生成列表:

$ pacman-disowned > non-db.txt

注意删除 non-db.txt 中的文件时先仔细确认。有写是配置文件、日志等,不要删除它们。

删除孤立软件包

递归删除孤立软件包:

# pacman -Rs $(pacman -Qtdq)

下面命令可以插入 $HOME/.bashrc 并在找到孤立软件包时进行删除:

orphans() {
  if [[ ! -n $(pacman -Qdt) ]]; then
    echo no orphans to remove
  else
    sudo pacman -Rs $(pacman -Qdtq)
  fi
}

删除base软件包组以外的所有软件包

以下命令会保留base软件包组、删除其他所有软件包:

# pacman -Rs $(comm -23 <(pacman -Qeq|sort) <((for i in $(pacman -Qqg base); do pactree -ul $i; done)|sort -u|cut -d ' ' -f 1))

来源:这个帖子

注记:

  1. comm命令需要已排序的输入,否则会得到诸如“comm: file 1 is not in sorted order”之类的错误信息。
  2. pactree是生成软件包依赖树的工具,输出如下:
$ pactree -lu logrotate
logrotate
popt
glibc
linux-api-headers
tzdata
dcron cron
bash
readline
ncurses
gzip

为了避免“dcron cron”(前者是软件包名,后者是该软件包提供的软件包名)这样的内容导致错误,用到了cut -d ' ' -f 1——只保留软件包名称。

仅显示正式安装的软件包

pacman -Qq |grep -Fv -f <(pacman -Qqm)

安装和修复

几种获取和修复软件包的方法。

从 CD/DVD/ISO 安装软件包

  • 先挂载 CD (如果需要,替换cdromdvd或其他介质):
# mount /mnt/cdrom
如果使用的是ISO映像,先在 /mnt 建立一个目录:
# mkdir /mnt/iso
然后挂载镜像:
# mount -t iso9660 -o ro,loop /path/to/iso /mnt/iso
  • 配置pacman:
# nano -w /etc/pacman.conf
  • 将如下仓库信息添加到其他软件仓库(如 extra、core)之前,确保优先使用介质中的软件包:
# 使用 cdrom 作为仓库
[custom]
Server = file:///mnt/cdrom/arch/pkg
如果使用其他介质,记得替换 cdrom

修改pacman.conf后,更新软件仓库即可。

从 Arch 的 core 镜像安装软件包

如果暂时无法链接网络(比如要配置无线网络),可以通过Arch的core仓库镜像获取软件包。先挂载之:

# mount -o loop /path/to/arch_core_image/i686/repo-core-i686.sfs /mnt/iso

然后修改pacman.conf[core]段,(临时)替换为镜像挂载的位置:

[core]
#Include = /etc/pacman.d/mirrorlist
Server = file:///mnt/iso

然后同步:

# pacman -Syu

自建本地仓库

pacman 3 引入了一个名为repo-add脚本,用于帮助个人用户生成软件仓库。使用 repo-add --help 查看详细用法。

将所有要加入仓库的软件包放入一个目录,运行如下命令(repo是自建仓库的名称):

$ repo-add /path/to/repo.db.tar.gz /path/to/*.pkg.tar.xz

注意,repo-add生成的数据库文件不一定和软件包放在同一目录,但使用pacman同步时,两者必须放在一起。

向仓库添加新软件包(并移除旧的):

$ repo-add /path/to/repo.db.tar.gz /path/to/packagetoadd-1.0-1-i686.pkg.tar.xz
注意: 使用repo-remove删除软件包。

本地仓库建立后,添加仓库到pacman.confdb.tar.gz文件的名字就是仓库的名字,路径格式是file://...或FTP地址ftp://localhost/path/to/directory

欢迎到非官方用户软件仓库,分享你的仓库。

在网络上共享pacman缓存

小贴士: 另外一个方案:pacserve

要在多机间共享软件包,使用任何网络协议共享/var/cache/pacman/目录即可。本节介绍如何使用shfs或sshfs,在局域网内的多机间分享软件包及相关库文件目录。注意,网络间共享可能速度缓慢,取决于所选文件系统等因素。

首先,在服务器安装任意网络文件系统:sshfsshfsftpfssmbfsnfs

小贴士: 使用sshfs或shfs前,先阅读Using SSH Keys

然后,挂载服务器的/var/cache/pacman/pkg到客户端机器上的/var/cache/pacman/pkg目录即可。

要分享软件包数据,使用同样方法共享/var/lib/pacman/sync/{core,extra,testing,community}即可。修改/etc/fstab以开机自动挂载。

避免过度清理缓存

执行pacman -Sc清理软件包缓存时,会删除所有当前机器上为安装的软件包。由于pacman无法判断软件包是否在其他机器上安装,这会导致移除某些还需要的软件包。

避免的方法是修改清理方式为:删除所有已有新版本的过期软件包。添加以下内容到/etc/pacman.conf[options]段:

CleanMethod = KeepCurrent

备份和恢复已安装软件包

定期备份软件包是个好习惯。万一系统出了大问题,需要重装,就可以利用备份的软件包恢复到原先的系统。

  • 第一步,生成系统上安装的非本地(即从官方仓库获取的)软件包列表:
 $ comm -23 <(pacman -Qeq|sort) <(pacman -Qmq|sort) > pkglist
  • 把生成的pkglist存储在一个安全的地方,比如U盘,或者gist.github.com、evernote、dropbox之类的文本储存网站。
  • 今后重装系统时,把pkglist复制到新系统。
  • 使用如下命令安装所有软件包:
 # pacman -S $(< pkglist)

要是备份的软件包列表包含非官方软件包(从AUR或其他什么地方下载的),就得使用下面这个吓人的命令了,不然pacman会出错:

# pacman -S --needed $(diff <(cat badpkglist|sort) <(diff <(cat badpkglist|sort) <(pacman -Slq|sort)|grep \<|cut -f2 -d' ')|grep \<|cut -f2 -d' ')

解释:

  • pacman -Slq列出所有可以安装的软件包。由于输出是按照来源仓库排序的,需要再调用sort排序。
  • 排序是为diff命令比对列表做准备。
  • 第一个diff返回所有无法安装的软件包;第二个返回所有可以安装的软件包。
  • --needed表示跳过已安装软件包。

可以接着用yaourt恢复从AUR获取的软件包(不推荐):

$ yaourt -S --noconfirm $(diff <(cat badpkglist|sort) <(pacman -Slq|sort) |grep \<|cut -f2 -d' ')

最后,还可以卸载掉新系统上安装的、但之前系统并未安装的软件包。 警告:务必小心使用,仔细查看pacman输出,避免悲剧。

# pacman -Rsu $(diff <(cat badpkglist|sort) <(pacman -Qq|sort) | grep \>|cut -f2 -d' ')

列出所有不属于base或base-devel的已安装软件包

下列命令输出所有不属于base或base-devel软件包组的已安装软件包。这些软件包一般都是用户自己安装的:

comm -23 <(pacman -Qeq|sort) <(pacman -Qgq base base-devel|sort)

重新安装所有软件包

要是你的系统遭到了大规模破坏(比如rm -rf什么的),可以通过pacman重新安装所有软件包来挽救。

如果没有安装外来软件包(比如来自AUR的),使用如下命令即可:

# pacman -Qeq | pacman -S -
# pacman -Qdq | pacman -S --asdeps -

如果安装了外来软件包,使用上面的命令会出错。下面的命令先生成所有软件包列表,再用pacman -Qmq剔除外来软件包,即重新安装所有仓库中可以找到的软件包,同时保留依赖安装、手动安装标志:

# comm -23 <(pacman -Qeq) <(pacman -Qmq) | pacman -S -
# comm -23 <(pacman -Qdq) <(pacman -Qmq) | pacman -S --asdeps -

恢复pacman本地数据库

如果遇到下面的问题,很可能需要恢复pacman本地数据库:

  • pacman -Q什么都不输出,pacman -Syu错误地报告系统已为最新。
  • 使用pacman -S安装软件包时,很多已经安装过的依赖提示未安装。

pacman储存本地软件包的数据库/var/lib/pacman/local很可能已经损坏甚至丢失。这是很严重的问题,请按照如下步骤修复。

首先,确认pacman的日志文件还在:

$ ls /var/log/pacman.log

如果日志丢失了,那就不能使用本方法修复,可以尝试使用Xyne的软件包检测脚本重建数据库。要是还行不通,很遗憾,最后的路就是重装系统。

日志过滤脚本

创建一个awk脚本文件,内容如下 基于[1]

log2pkglist.awk
#!/bin/awk -f

$3 ~ /^(installed|upgraded)$/ {
  pkg[$4] = 1
  next
} 

$3 == "removed" {
  pkg[$4] = 0
} 

END {
  for (i in pkg) if (pkg[i]) print i
}

打上可执行标志:

$ chmod +x log2pkglist.awk

生成软件包列表

运行该脚本,输出到一个文本文件中:

$ ./log2pkglist.awk /var/log/pacman.log > pkglist.orig

(可选)手动检查pkglist.orig,删除所有不需要重新安装的软件包,例如:自己从ABS安装的软件包。

过滤掉无法从软件仓库中安装的软件包:

$ { cat pkglist.orig; pacman -Slq; } | sort | uniq -d > pkglist

检查base软件包组中的软件包是否缺失,并加入列表:

$ comm -23 <(pacman -Sgq base) pkglist.orig >> pkglist

pkglist列表内容完备后,继续下一步,利用这个列表恢复数据库。

恢复数据库

建立临时的缓存、数据库以及根目录:

tmp=~/tmp
mkdir -p "${tmp}"

pushd "${tmp}"
dbpath=$(readlink -f ./dbpath)
root=$(readlink -f ./root)
cache=$(readlink -f ./cache)
log=/dev/null
mkdir -p "${dbpath}" "${cache}" "${root}"
popd

recovery-pacman() {
  fakeroot pacman "$@"   \
    --dbpath "${dbpath}" \
    --root   "${root}"   \
    --cache  "${cache}"  \
    --log    "${log}"    \
    --noscriptlet        \
    #
}

同步临时目录中的数据库:

$ recovery-pacman -Sy

或者复制系统的数据库:

$ cp -r /var/lib/pacman/sync "${dbpath}"

(可选)要避免下载和处理当前系统本地数据库中存在的软件包,复制本地数据库到临时目录:

$ cp -r /var/lib/pacman/local "${dbpath}"

从上一步获取的pkglist生成临时本地数据库:

$ recovery-pacman -S --nodeps --needed $(< pkglist)
注意: 由于--noscriptlet选项,fakeroot生成的文件不会被真正安装到系统中。

生成数据库后,复制到真正的系统中:

# cp -r "${dbpath}"/local /var/lib/pacman

最后,更新本地数据库,将不受其他软件包依赖的软件包标记为手动安装,剩下的标记为依赖安装:

# pacman -D --asdeps $(pacman -Qq)
# pacman -D --asexplicit $(pacman -Qtq)

从已有安装修复 USB 系统

如果你有一个Arch安装在U盘上,不小心搞坏了(比如,写入U盘时断电了),可以使用主机上的Arch修复U盘上的Arch(假设U盘挂载在/newarch):

# pacman -S $(pacman -Qq --dbpath /newarch/var/lib/pacman) --root /newarch --dbpath /newarch/var/lib/pacman

解压缩软件包

Arch软件包其实就是普通的xz压缩包,解压方法没啥特别的:

$ tar -Jxvf package.tar.xz