Pacman/ヒントとテクニック

提供: ArchWiki
2015年12月28日 (月) 11:36時点におけるAosho235 (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

関連記事

pacman を新しく使い始めた人向けのヒント集。

目次

外観と利便性の向上

カラー出力

バージョン 4.1 から Pacman にはカラーオプションが付きました。pacman.conf の中の "Color" という行をアンコメントしてください。

アップデート前にバージョンを比較する

アップデートする前に今インストールされているバージョンと新しいバージョンを表示するには、/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 コマンドの入力の手間を省くスクリプトエイリアスを説明しています。

シェルの設定

以下の例を追加して下さい、BashZsh のどちらでも動作します:

# pacman エイリアスの例
alias pacupg="sudo pacman -Syu"     # リポジトリと同期し、古くなっているパッケージをアップデートする
alias pacdl="pacman -Sw"            # 指定パッケージを .tar.xz としてダウンロードする
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 paclo="pacman -Qdt"           # 全ての孤児パッケージを表示する
alias pacc="sudo pacman -Scc"       # キャッシュ中の全パッケージを削除する
alias paclf="pacman -Ql"            # 指定パッケージによりインストールされたファイルのリストを表示する
alias pacown="pacman -Qo"           # 指定ファイルを所有するパッケージを表示する
alias pacexpl="pacman -D --asexp"   # 1個以上のインストール済みパッケージを「明示的にインストールされた」とマークする 
alias pacimpl="pacman -D --asdep"   # 1個以上のインストール済みパッケージを「依存関係によりインストールされた」とマークする

# さらなる pacman エイリアスの例
alias pacupd="sudo pacman -Sy && sudo abs"         # ローカルのパッケージと ABS のデータベースをリポジトリと同期する
alias pacinsd="sudo pacman -S --asdeps"            # 指定パッケージを依存関係としてインストールする
alias pacmir="sudo pacman -Syy"                    # /etc/pacman.d/mirrorlist を更新した後でパッケージのリストを強制的にリフレッシュする

以下のコマンドも便利ですが、危険でもあります。使用する時は、何が起こるのか完全に理解するようにしてください:

# 以下の pacman のメッセージに対処する:
# 
#     error: couldnt lock database: file exists
#     if you are sure a package manager is not already running, you can remove /var/lib/pacman/db.lck

alias pacunlock="sudo rm /var/lib/pacman/db.lck"   # ロックファイル /var/lib/pacman/db.lck を削除する
alias paclock="sudo touch /var/lib/pacman/db.lck"  # ロックファイル /var/lib/pacman/db.lck を作成する

使用方法

エイリアスの名前を入力するだけでそれぞれのコマンドが実行できます。例えば、リポジトリを同期して古くなっているパッケージをアップグレードするには:

$ pacupg

リポジトリからパッケージをインストール:

$ pacin <package1> <package2> <package3>

カスタムビルドパッケージをインストール:

$ pacins /path/to/<package>

インストールしたパッケージを完全に削除:

$ pacrem <package>

リポジトリからパッケージを検索:

$ pacreps <keywords>

リポジトリにあるパッケージの情報 (サイズ、依存関係など) を表示:

$ pacrep <keywords>

ノート

上記のエイリアスは例にすぎません。構文サンプルに従って、便利なようにエイリアスの名前を変えることが可能です。例えば:

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

上の場合、コマンド pacrempacout はどちらも同じコマンドを実行します。

オペレーションと Bash 構文

pacman の標準の機能に加えて、初歩的な Bash コマンド・構文を使うことでユーザビリティを拡張する方法が存在します。

  • 名前に同じようなパターンがあるパッケージを多数インストールする必要があり、グループ全体やマッチするパッケージ全てはインストールしないとき。例えば kde:
# pacman -S kde-{applets,theme,tools}
  • もちろん、これに制限はなく、拡張することができます:
# pacman -S kde-{ui-{kde,kdemod},kdeartwork}
  • 場合によっては、-s が不必要な多くの結果を招いてしまうことがあります。こういうときにはパッケージの名前だけにマッチするように(説明やその他のフィールドには引っかからないように)制限をかけることが可能です:
# pacman -Ss '^vim-'
  • pacman にはバージョンカラムを隠す -q オペランドがあり、"compiz" を名前の一部に含むパッケージを再インストールしたりすることが可能です:
# pacman -S $(pacman -Qq | grep compiz)
  • もしくはリポジトリのパッケージ全てをインストールしてください (例: kde-unstable):
# pacman -S $(pacman -Slq kde-unstable)

メンテナンス

The Arch Way に従ってシステムを清潔に保つための管理業務。

システムメンテナンスも参照。

最後にインストールしたパッケージを表示

expac をインストールして expac --timefmt='%Y-%m-%d %T' '%l\t%n' | sort | tail -20 または expac --timefmt=%s '%l\t%n' | sort -n | tail -20 を実行してください。

インストールしたパッケージを容量と一緒にリストアップ

容量でソートしたインストール済みパッケージの一覧を見ることができます、これはハードドライブの空き容量を増やしたいときに役立ちます。

  • expac をインストールして expac -s "%-30n %m" | sort -hk 2 | awk '{printf "%s %.0f MiB\n", $1, $2/1024/1024}' | column -t を実行する。
  • pacgraph に -c オプションを付けて実行することで全てのインストールしたパッケージと容量のリストを作成できます。pacgraph は [community] からインストールできます。
  • base や base-devel に含まれていない明示的にインストールしたパッケージを容量や説明と共に一覧する: expac -HM "%011m\t%-20n\t%10d" $( comm -23 <(pacman -Qqen|sort) <(pacman -Qqg base base-devel|sort) ) | sort -n

インストールしたパッケージをバージョンと一緒にリストアップ

バグを報告したりインストールしたパッケージについて議論するときに、インストールしたパッケージのリストをパッケージのバージョンと一緒に取得する良いでしょう。

  • 明示的にインストールしたパッケージを全て一覧する: pacman -Qe
  • 外部からインストールしたパッケージを一覧する (通常は手動でダウンロード・インストールしたパッケージ): pacman -Qm
  • 全てのネイティブなパッケージを一覧する (同期データベースからインストールしたパッケージ): pacman -Qn .
  • 正規表現でパッケージを一覧する: pacman -Qs <regex> | awk 'BEGIN { RS="\n" ; FS="/" } { print $2 }' | awk '{ if(NF > 0) print $1, $2 }'
  • expac をインストールして expac -s "%-30n %v" を実行する

アップデートを確認する

Pacman には checkupdates というスクリプトが付属しています。実行するのに root 権限は必要ありません。

ファイルがどのパッケージにも所有されていないことを確認

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 /etc /opt /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 に載っているファイルを全て削除するのはよくありません。様々な設定ファイルやログなどがあるかもしれないので、grep を使って相互参照を広く確実に検索した後でこのリストを使うようにしてください。

以下は役に立つワンライナーのスクリプトです。

どのパッケージにも属していないディレクトリを表示:

alias pacman-disowned-dirs="comm -23 <(sudo find / \( -path '/dev' -o -path '/sys' -o -path '/run' -o -path '/tmp' -o -path '/mnt' -o -path '/srv' -o -path '/proc' -o -path '/boot' -o -path '/home' -o -path '/root' -o -path '/media' -o -path '/var/lib/pacman' -o -path '/var/cache/pacman' \) -prune -o -type d -print | sed 's/\([^/]\)$/\1\//' | sort -u) <(pacman -Qlq | sort -u)"

どのパッケージにも属していないファイルを表示:

alias pacman-disowned-files="comm -23 <(sudo find / \( -path '/dev' -o -path '/sys' -o -path '/run' -o -path '/tmp' -o -path '/mnt' -o -path '/srv' -o -path '/proc' -o -path '/boot' -o -path '/home' -o -path '/root' -o -path '/media' -o -path '/var/lib/pacman' -o -path '/var/cache/pacman' \) -prune -o -type f -print | sort -u) <(pacman -Qlq | sort -u)"

孤立したパッケージの削除

再帰的に孤立したパッケージ(とその設定ファイル)を削除するには:

# pacman -Rns $(pacman -Qtdq)

孤立したパッケージが見つからなかった場合、pacman は error: no targets specified を出力します。pacman -Rns に何も引数が指定されていないとこうなります。

以下の関数を ~/.bashrc に挿入することで孤立したパッケージを簡単に削除できます:

~/.bashrc
orphans() {
  if [[ ! -n $(pacman -Qdt) ]]; then
    echo "No orphans to remove."
  else
    sudo pacman -Rns $(pacman -Qdtq)
  fi
}
ノート: 上記のスクリプトやコマンドは本当は孤立していないパッケージを表示する可能性があるため、実は孤立パッケージでないパッケージを削除する危険性があります。本当に孤立しているパッケージだけを削除するようにしたい場合、pkg_scriptsAUR パッケージの pkg-list_true_orphans を使って下さい。

使用していないパッケージの削除

システムは軽いほうがメンテナンスしやすいので、ときどき明示的にインストールパッケージを眺めて、使用していないパッケージを削除するべきだと手動で選択すると良いでしょう。

公式リポジトリに含まれているパッケージで明示的にインストールしたパッケージを表示するには:

$ pacman -Qen

公式リポジトリに含まれていないパッケージで明示的にインストールしたパッケージを表示するには:

$ pacman -Qem

base グループ以外の全てのパッケージを削除する

base グループを除く全てのパッケージを削除する必要がある場合は、このワンライナーを試して下さい:

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

ソース: Look at discussion here

ノート:

  1. comm requires sorted input otherwise you get e.g. comm: file 1 is not in sorted order.
  2. pactree prints the package name followed by what it provides. For example:
$ pactree -lu logrotate
logrotate
popt
glibc
linux-api-headers
tzdata
dcron cron
bash
readline
ncurses
gzip

The dcron cron line seems to cause problems, that is why cut -d ' ' -f 1 is needed - to keep just the package name.

公式にインストールされたパッケージのみを一覧する

$ pacman -Qqn

同期データベースに存在するパッケージを一覧します。非公式のリポジトリを設定している場合は、そのリポジトリからインストールしたパッケージも表示されます。

複数のパッケージの依存パッケージ一覧を取得

Dependencies are alphabetically sorted and doubles are removed. Note that you can use pacman -Qi to improve response time a little. But you will not be able to query as many packages. Unfound packages are simply skipped (hence the 2>/dev/null). You can get dependencies of AUR packages as well if you use yaourt -Si, but it will slow down the queries.

$ pacman -Si $@ 2>/dev/null | awk -F ": " -v filter="^Depends" \ '$0 ~ filter {gsub(/[>=<][^ ]*/,"",$2) ; gsub(/ +/,"\n",$2) ; print $2}' | sort -u

もしくは、expac を使うことも可能です: expac -l '\n' %E -S $@ | sort -u

複数のパッケージの容量を取得

以下のシェル関数を使うことができます:

~/.bashrc
pacman-size()
{
	CMD="pacman -Si"
	SEP=": "
	TOTAL_SIZE=0
	
	RESULT=$(eval "${CMD} $@ 2>/dev/null" | awk -F "$SEP" -v filter="Size" -v pkg="^Name" \
	  '$0 ~ pkg {pkgname=$2} $0 ~ filter {gsub(/\..*/,"") ; printf("%6s KiB %s\n", $2, pkgname)}' | sort -u -k3)
	
	echo "$RESULT"
	
	## Print total size.
	echo "$RESULT" | awk '{TOTAL=$1+TOTAL} END {printf("Total : %d KiB\n",TOTAL)}'
}

依存関係リストと同じように pacman -Qi を代わりに使うこともできますが、AUR の PKGBUILD にサイズ情報は含まれていないので yaourt では出来ません。

ワンライナー:

$ pacman -Si "$@" 2>/dev/null | awk -F ": " -v filter="Size" -v pkg="Name" '$0 ~ pkg {pkgname=$2} $0 ~ filter {gsub(/\..*/,"") ; printf("%6s KiB %s\n", $2, pkgname)}' | sort -u -k3 | tee >(awk '{TOTAL=$1+TOTAL} END {printf("Total : %d KiB\n",TOTAL)}')

You should replace "$@" with packages, or put this line in a shell function.

変更された設定ファイルを一覧する

If you want to backup your system configuration files you could copy all files in /etc/, but usually you're only interested in the files that you have changed. In this case you want to list those changed configuration files, we can do this with the following command:

# pacman -Qii | awk '/^MODIFIED/ {print $2}'

The following script does the same. You need to run it as root or with sudo.

changed-files.sh
#!/bin/bash
for package in /var/lib/pacman/local/*; do
	sed '/^%BACKUP%$/,/^%/!d' $package/files | tail -n+2 | grep -v '^$' | while read file hash; do
		[ "$(md5sum /$file | (read hash file; echo $hash))" != "$hash" ] && echo $(basename $package) /$file
	done
done

依存されていないパッケージを全て表示する

インストールしたパッケージの中で、どのパッケージにも依存されていないパッケージのリストを生成したい場合、以下のスクリプトを使うことができます。ハードドライブの容量を増やそうとしていて、覚えがない大量のパッケージがインストールされている場合、このスクリプトはとても役に立ちます。出力を見ることで必要なくなったパッケージを見つけることができます。

ノート: このスクリプトは明示的にインストールしたパッケージも含めて、どのパッケージにも依存されていない全てのパッケージを表示します。依存パッケージとしてインストールされていながら、どのパッケージにも必要とされていないパッケージを表示するには、#孤立したパッケージの削除 を見て下さい。
clean
#!/bin/bash

# This script is designed to help you clean your computer from unneeded
# packages. The script will find all packages that no other installed package
# depends on. It will output this list of packages excluding any you have
# placed in the ignore list. You may browse through the script's output and
# remove any packages you do not need.

# Enter groups and packages here which you know you wish to keep. They will
# not be included in the list of unrequired packages later.
ignoregrp="base base-devel"
ignorepkg=""

comm -23 <(pacman -Qqt | sort) <(echo $ignorepkg | tr ' ' '\n' | cat <(pacman -Sqg $ignoregrp) - | sort -u)

パッケージの説明も見るには:

expac -HM "%-20n\t%10d" $( comm -23 <(pacman -Qqt|sort) <(pacman -Qqg base base-devel|sort) )

Systemd を使ってローカルデータベースをバックアップ

systemd は pacman のローカルデータベースのスナップショットを(データベースが変更される度に)作成することができます。

ノート: AUR にもっと細かく設定できるバージョンがあります: pakbak-gitAUR

以下のスクリプトを使って下さい ($pakbak の値はバックアップ先に置き換えて下さい)。pakbak.service有効化することで起動時に自動的に実行させることができます:

/usr/lib/systemd/scripts/pakbak_script
#!/bin/bash

declare -r pakbak="/pakbak.tar.xz";  ## set backup location
tar -cJf "$pakbak" "/var/lib/pacman/local";  ## compress & store pacman local database in $pakbak
/usr/lib/systemd/system/pakbak.service
[Unit]
Description=Back up pacman database

[Service]
Type=oneshot
ExecStart=/bin/bash /usr/lib/systemd/scripts/pakbak_script
RemainAfterExit=no
/usr/lib/systemd/system/pakbak.path
[Unit]
Description=Back up pacman database

[Path]
PathChanged=/var/lib/pacman/local
Unit=pakbak.service

[Install]
WantedBy=multi-user.target

インストールとリカバリー

パッケージを取得・復活させる他の方法。

パッケージを CD/DVD や USB スティックからインストールする

パッケージや、パッケージグループをダウンロードするには:

# cd ~/Packages
# pacman -Syw base base-devel grub-bios xorg gimp --cachedir .
# repo-add ./custom.db.tar.gz ./*

ダウンロードしたら "Packages" フォルダを CD/DVD に焼くか USB スティック、外部 HDD などにコピーしてください。

インストールするには:

1. メディアをマウントする:

# mkdir /mnt/repo
# mount /dev/sr0 /mnt/repo    # CD/DVD の場合
# mount /dev/sdxY /mnt/repo   # USB スティックの場合。

2. pacman.conf を編集して他のリポジトリ (例: extra, core, etc.) の前にリポジトリを追加してください。この手順は重要です。これで標準のリポジトリに優先して CD/DVD/USB のファイルがインストールされるようになります:

# nano /etc/pacman.conf
[custom]
SigLevel = PackageRequired
Server = file:///mnt/repo/Packages

3. 最後に、pacman データベースを同期して新しいリポジトリを使えるようにしてください:

# pacman -Sy

カスタムローカルリポジトリ

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
ノート: If there is a package that needs to be removed from the repository, read up on repo-remove.

ローカルリポジトリを作成できたら、リポジトリを pacman.conf に追加してください。db.tar.gz ファイルの名前がリポジトリの名前です。file:// url を使って直接参照するか、ftp://localhost/path/to/directory を使って FTP でアクセスしてください。

カスタムリポジトリを非公式ユーザーリポジトリに追加すれば、コミュニティはそれを使うことができるようになります。

pacman のキャッシュをネットワークで共有する

読み取り専用キャッシュ

If you're looking for a quick and dirty solution, you can simply run a standalone webserver which other computers can use as a first mirror: darkhttpd /var/cache/pacman/pkg. Just add this server at the top of your mirror list. Be aware that you might get a lot of 404 errors, due to cache misses, depending on what you do, but pacman will try the next (real) mirrors when that happens.

読み書き可能キャッシュ

ヒント: See pacserve for an alternative (and probably simpler) solution than what follows.

複数のコンピュータ間でパッケージを共有するには、ネットワークベースのマウントプロトコルを使って /var/cache/pacman/ を共有します。このセクションでは shfs または sshfs を使ってパッケージキャッシュと関連するライブラリディレクトリを同一ローカルネットワーク上の複数のコンピュータで共有する方法を示します。ネットワークで共有されるキャッシュは、ファイルシステムの選択やその他の要因で、遅くなることがあります。

まず、ネットワークをサポートするファイルシステムをインストールしてください。例えば sshfs, shfs, ftpfs, smbfs, nfs など。

ヒント: sshfs や shfs を使う場合、SSH 鍵を読んで下さい。

Then, to share the actual packages, mount /var/cache/pacman/pkg from the server to /var/cache/pacman/pkg on every client machine.

BitTorrent Sync を使って pacman のパッケージキャッシュを同期する

BitTorrent Sync はネットワークを介してフォルダを同期する新方法です (LAN でもインターネットでも動作します)。ピアツーピアなのでサーバーを設定する必要はありません: 詳しくはリンクを参照してください。 BitTorrent Sync を使って pacman のキャッシュを共有する方法:

  • まず同期したいマシンに AUR から btsyncAUR パッケージをインストール。
  • BitTorrent Sync の wiki ページや AUR パッケージのインストール手順に従う。
    • set up BitTorrent Sync to work for the root account. This process requires read/write to the pacman package cache.
    • make sure to set a good password on btsync's web UI
    • btsync の systemd デーモンを起動。
    • in the btsync Web GUI add a new synchronized folder on the first machine and generate a new Secret. Point the folder to /var/cache/pacman/pkg
    • Add the folder on all the other machines using the same Secret to share the cached packages between all systems. Or, to set the first system as a master and the others as slaves, use the Read Only Secret. Be sure to point it to /var/cache/pacman/pkg

Now the machines should connect and start synchronizing their cache. Pacman works as expected even during synchronization. The process of syncing is entirely automatic.

要らなくなったキャッシュが消えないようにする

By default, pacman -Sc removes package tarballs from the cache that correspond to packages that are not installed on the machine the command was issued on. Because pacman cannot predict what packages are installed on all machines that share the cache, it will end up deleting files that should not be.

To clean up the cache so that only outdated tarballs are deleted, add this entry in the [options] section of /etc/pacman.conf:

CleanMethod = KeepCurrent

インストールしたパッケージのリストのバックアップと復旧

pacman によってインストールしたパッケージのバックアップを定期的に行うのはグッドプラクティスです。何らかの理由でリカバリーできないシステムクラッシュが発生した時、pacman を使って全く同じパッケージを簡単に新しい環境に再インストールすることができるようになります。

  • まず、ローカルにない現在のパッケージの一覧をバックアップしてください: $ pacman -Qqen > pkglist.txt
  • pkglist.txt を USB キーやその他メディア gist.github.com, Evernote, Dropbox などに保存してください。
  • pkglist.txt ファイルを新しいインストールにコピーして、ファイルが含まれているディレクトリにまで移動してください。
  • 次のコマンドを実行することでバックアップリストからインストールを行います: # pacman -S $(< pkglist.txt)

上記のようにリストが生成されない場合、おそらく foreign パッケージ (設定したリポジトリに存在しないパッケージ、もしくは AUR のパッケージ) が存在します。

そのような場合でも、リストから利用可能なパッケージを全てインストールすることができます:

# pacman -S --needed $(comm -12 <(pacman -Slq|sort) <(sort badpkdlist) )

説明:

  • pacman -Slq lists all available softwares, but the list is sorted by repository first, hence the sort command.
  • comm コマンドを動作させるにはファイルをソートする必要があります。
  • -12 パラメータは両方のエントリで共通する行を表示します。
  • --needed スイッチを使うことで既にインストールされているパッケージはスキップされます。

yaourt を使うことで AUR からリポジトリにないパッケージを全てインストールするのを試行することもできます (何がおこるかわかってない場合は推奨しません):

$ yaourt -S --needed $(comm -13 <(pacman -Slq|sort) <(sort badpkdlist) )

最後に、リストに記されていない全てのパッケージをシステム上から削除することができます:

警告: このコマンドは注意して使って下さい、pacman の出力をよくチェックしましょう。
# pacman -Rsu $(comm -23 <(pacman -Qq|sort) <(sort pkglist))

base や base-devel に存在しないダウンロード済みパッケージを一覧

次のコマンドは basebase-devel に存在しない、ユーザーが手動でインストールしたパッケージを全て表示します:

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

インストールしたパッケージの中で特定のリポジトリに存在しないパッケージを表示するには (例えば repo_name):

$ comm -23 <(pacman -Qtq | sort) <(pacman -Slq repo_name | sort)

インストールしたパッケージの中で repo_name リポジトリに存在するパッケージを表示するには:

$ comm -12 <(pacman -Qtq | sort) <(pacman -Slq repo_name | sort)

全てのパッケージの再インストール

全てのネイティブのパッケージを再インストールするには、次を使って下さい:

# pacman -Qenq | pacman -S -

外部の (AUR) パッケージは別に再インストールする必要があります。外部のパッケージは pacman -Qemq で一覧できます。

デフォルトで Pacman はインストールの理由(明示的にインストールしたか、依存でインストールしたか)を維持します。

pacman のローカルデータベースを復元する

ローカルデータベースの復元が必要だと pacman が示す場合:

  • pacman -Q で何も出力がされず、pacman -Syu でシステムが最新だと表示されるとき。
  • pacman -S package を使ってパッケージをインストールしようとすると、既にインストールされている依存パッケージのリストが出力される。
  • (pacman に含まれている) testdb でデータベースが壊れていると表示される。

以上の場合、十中八九、インストールしたソフトウェアの pacman データベースである /var/lib/pacman/local が破損していたり削除されています。これは深刻な問題ですが、以下の手順に従うことで復元することができます。

まず、pacman のログファイルが存在するか確認します:

$ ls /var/log/pacman.log

ログファイルが存在しない場合は、この方法で続行することは不可能です。Xyne のパッケージ検出スクリプト を使ってデータベースを再作成してみてください。それができない場合、解決方法としてはシステム全体を再インストールするしかありません。

ログフィルタースクリプト

pacrecover
#!/bin/bash -e

. /etc/makepkg.conf

PKGCACHE=$((grep -m 1 '^CacheDir' /etc/pacman.conf || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir = //')

pkgdirs=("$@" "$PKGDEST" "$PKGCACHE")

while read -r -a parampart; do
  pkgname="${parampart[0]}-${parampart[1]}-*.pkg.tar.xz"
  for pkgdir in ${pkgdirs[@]}; do
    pkgpath="$pkgdir"/$pkgname
    [ -f $pkgpath ] && { echo $pkgpath; break; };
  done || echo ${parampart[0]} 1>&2
done

スクリプトを実行可能にしてください:

$ chmod +x pacrecover

パッケージの復旧リストを生成する

警告: If for some reason your pacman cache or makepkg package destination contain packages for other architectures, remove them before continuation.

スクリプトを実行してください (任意でパッケージが含まれている追加のディレクトリをパラメータで渡して下さい):

$ paclog-pkglist /var/log/pacman.log | ./pacrecover >files.list 2>pkglist.orig

このコマンドで2つのファイルが作成されます: マシンに存在するパッケージファイルが載った files.list と、ダウンロードするべきパッケージが載った pkglist.orig です。後者ではマシンに存在する、古いバージョンのパッケージのファイルと、新しいバージョンのファイルでミスマッチが発生することがあります。ミスマッチは手動で修正する必要があります。

Here is a way to automatically restrict second list to packages available in a repository:

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

重要な base パッケージが欠けていないか確認して、リストに加えます:

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

Proceed once the contents of both lists are satisfactory, since they will be used to restore pacman's installed package database; /var/lib/pacman/local/.

リカバリを実行する

リカバリのための bash エイリアスを定義してください:

# recovery-pacman() {
    pacman "$@"       \
    --log /dev/null   \
    --noscriptlet     \
    --dbonly          \
    --force           \
    --nodeps          \
    --needed          \
    #
}

--log /dev/null allows to avoid needless pollution of pacman log, --needed will save some time by skipping packages, already present in database, --nodeps will allow installation of cached packages, even if packages being installed depend on newer versions. Rest of options will allow pacman to operate without reading/writing filesystem.

同期データベースを作成:

# pacman -Sy

files.list からローカルで利用可能なパッケージファイルをインストールしてデータベースの生成を開始:

# recovery-pacman -U $(< files.list)

pkglist から残りをインストール:

# recovery-pacman -S $(< pkglist)

Update the local database so that packages that are not required by any other package are marked as explicitly installed and the other as dependences. You will need be extra careful in the future when removing packages, but with the original database lost is the best we can do.

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

Optionally check all installed packages for corruption:

# pacman -Qk

任意でファイルがどのパッケージにも所有されていないことを確認してください。

全てのパッケージをアップデート:

# pacman -Su

既存のインストールから USB キーを回復させる

If you have Arch installed on a USB key and manage to mess it up (e.g. removing it while it is still being written to), then it is possible to re-install all the packages and hopefully get it back up and working again (assuming USB key is mounted in /newarch)

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

.pkg ファイルの中身を展開する

.xz で終わっている .pkg ファイルは tar で固められた圧縮ファイルであり、次のコマンドで解凍できます:

$ tar xvf package.tar.xz

ファイルを .pkg から展開したい場合、この方法を使うことができます。

.pkg ファイルに含まれているファイルを回覧する

例えば、systemd パッケージに入っている /etc/systemd/logind.conf の中身を見たいのならば:

$ tar -xOf /var/cache/pacman/pkg/systemd-204-3-x86_64.pkg.tar.xz etc/systemd/logind.conf

もしくは vim を使ってアーカイブをブラウズすることもできます:

$ vim /var/cache/pacman/pkg/systemd-204-3-x86_64.pkg.tar.xz

古いパッケージのライブラリを使っているアプリケーションを探す

Even if you installed a package the existing long-running programs (like daemons and servers) still keep using code from old package libraries. And it is a bad idea to let these programs running if the old library contains a security bug.

Here is a way how to find all the programs that use old packages code:

# lsof +c 0 | grep -w DEL | awk '1 { print $1 ": " $NF }' | sort -u

It will print running program name and old library that was removed or replaced with newer content.