「Pacman/ローカルデータベースの復元」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(文字列「[[zh-cn:」を「[[zh-hans:」に置換)
(コマンドを最新化、軽微な文言の修正)
31行目: 31行目:
   
 
while read -r -a parampart; do
 
while read -r -a parampart; do
pkgname="${parampart[0]}-${parampart[1]}-*.pkg.tar.xz"
+
pkgname="${parampart[0]}-${parampart[1]}-*.pkg.tar.{xz,zst}"
 
for pkgdir in ${pkgdirs[@]}; do
 
for pkgdir in ${pkgdirs[@]}; do
 
pkgpath="$pkgdir"/$pkgname
 
pkgpath="$pkgdir"/$pkgname
41行目: 41行目:
 
スクリプトを実行してください (任意でパッケージが含まれている追加のディレクトリをパラメータで渡して下さい):
 
スクリプトを実行してください (任意でパッケージが含まれている追加のディレクトリをパラメータで渡して下さい):
   
$ paclog-pkglist /var/log/pacman.log | ./pacrecover >files.list 2>pkglist.orig
+
$ paclog --pkglist --logfile=/var/log/pacman.log | ./pacrecover >files.list 2>pkglist.orig
   
 
このコマンドで2つのファイルが作成されます: マシンに存在するパッケージファイルが載った {{Ic|files.list}} と、ダウンロードするべきパッケージが載った {{Ic|pkglist.orig}} です。後者ではマシンに存在する、古いバージョンのパッケージのファイルと、新しいバージョンのファイルでミスマッチが発生することがあります。ミスマッチは手動で修正する必要があります。
 
このコマンドで2つのファイルが作成されます: マシンに存在するパッケージファイルが載った {{Ic|files.list}} と、ダウンロードするべきパッケージが載った {{Ic|pkglist.orig}} です。後者ではマシンに存在する、古いバージョンのパッケージのファイルと、新しいバージョンのファイルでミスマッチが発生することがあります。ミスマッチは手動で修正する必要があります。
51行目: 51行目:
 
重要な ''base'' パッケージが欠けていないか確認して、リストに加えます:
 
重要な ''base'' パッケージが欠けていないか確認して、リストに加えます:
   
$ comm -23 <(pacman -Sgq base) pkglist.orig >> pkglist
+
$ comm -23 <(pacman -Sgq base | sort) pkglist.orig >> pkglist
   
 
両方のリストの中身が問題ないようでしたら、次に進んでください。リストを使用して pacman のパッケージデータベースを復旧します: {{ic|/var/lib/pacman/local/}}。
 
両方のリストの中身が問題ないようでしたら、次に進んでください。リストを使用して pacman のパッケージデータベースを復旧します: {{ic|/var/lib/pacman/local/}}。
57行目: 57行目:
 
== リカバリを実行する ==
 
== リカバリを実行する ==
   
リカバリのための bash エイリアスを定義してください:
+
リカバリのための bash 関数を定義してください:
   
recovery-pacman() {
+
recovery-pacman() {
sudo pacman "$@" \
+
pacman "$@" \
 
--log /dev/null \
 
--log /dev/null \
 
--noscriptlet \
 
--noscriptlet \
 
--dbonly \
 
--dbonly \
--force \
+
--overwrite "*" \
 
--nodeps \
 
--nodeps \
 
--needed
 
--needed

2023年2月4日 (土) 11:45時点における版

ローカルデータベースの復元が必要だとわかる兆候:

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

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

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

$ ls /var/log/pacman.log

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

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

警告: 何らかの理由で pacman のキャッシュや makepkg の保存先に他のアーキテクチャのパッケージが含まれている場合、先に削除してください。

ログフィルタースクリプトを作成して実行可能権限を付与:

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,zst}"
  for pkgdir in ${pkgdirs[@]}; do
    pkgpath="$pkgdir"/$pkgname
    [ -f $pkgpath ] && { echo $pkgpath; break; };
  done || echo ${parampart[0]} 1>&2
done

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

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

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

以下のコマンドで自動的に後者のリストをリポジトリに存在するパッケージだけに絞ることができます:

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

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

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

両方のリストの中身が問題ないようでしたら、次に進んでください。リストを使用して pacman のパッケージデータベースを復旧します: /var/lib/pacman/local/

リカバリを実行する

リカバリのための bash 関数を定義してください:

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

--log /dev/null は不必要に pacman のログを生成することを避け、--needed は既にデータベースに存在するパッケージを省略し、--nodeps はキャッシュされているパッケージのインストールを許可します。他のオプションはファイルシステムを読み書きすることなく pacman を操作できるようにします。

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

# pacman -Sy

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

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

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

# recovery-pacman -S $(< pkglist)

ローカルデータベースを更新して、他のパッケージから必要とされてないパッケージを「明示的にインストールした」とし、他のパッケージを「依存パッケージ」とします。パッケージを削除するときは特別な注意が必要になりますが、データベースが壊れている以上これがベストです。

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

任意でインストールされたパッケージに破損が存在しないかチェックします:

# pacman -Qk

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

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

# pacman -Su