Debianでのとある作業中、未だかつてないドジを踏み、/var/lib/dpkg/infoディレクトリをまるごと削除してしまいました...。
こんなことをしでかしたのは、自分だけだろうな...と思ったら、過去にもいた模様、が、解決に至ったケースは限られ、これならいける!っていう決定打がないような...。
そこで試行錯誤した結果として生まれた解決策が、このワンライナーというかツーライナー。
その前に何かと後述のエラーが出ると思うので削除したinfoディレクトリを、また、そこにformat-newファイルを作成しておきます。
そして、ワンライナー2つ。
まずは、dpkg -l(インストール済みパッケージ)の情報を使ってreinstall。
続いてdpkg --audit(インストールされている模様も問題がありそうなパッケージを抽出する検査)の情報を使ってapt purge。
これらというか、前者は、マシンスペックやインストール済みパッケージの数等に応じて相当な時間がかかるので覚悟が必要です。
自身の場合、IntelデュアルコアCPU/RAM:4GBのPCで前者に約5時間半かかりました...、後者は計測しませんでしたが、覚悟した割には肩透かしをくらったようにすぐに終わった印象です。
apt purgeは、[apt(-get) remove --purge]と等価、[dpkg -P]も同様のようです。
単なるremoveがパッケージのみ削除するのと異なり、purgeは、対象パッケージだけでなく、インストール時に展開された設定ファイル類も削除します。
purge、というか、removeにおいては、どうやらパッケージによって、それを削除するならこれを代わりに入れとくぞ的なインストールが含まれることもあるようです。
(Debian Busterでたまたま確認したのは、EmpathyとPidginとか)
何が言いたいかというと、この時、削除済みパッケージの構成ファイルが残っていた(単にパッケージのみを削除するapt removeしたパッケージがあった)場合、構成ファイルを上書きする前に確認を求められることがあるので-yを渡したからと言って放置はできない可能性もある点に注意が必要ということです。
これで解決したわけですが、実行中は、削除されるものもあれば、「パッケージ xxx はインストールされていないため削除もされません」といったものもある一方、インストール済みだったパッケージの?インストールもしているようでデータベース登録数(「現在 xxx 個のファイルとディレクトリがインストールされています」)の数が、だんだん増えていっています。
解決直後に保存してあったdpkg --auditされたファイル群の一部をapt-cache searchしてみると存在するものもあれば、存在しないものもありました。
また、システムやメニューを眺めてもインストールしてあったものが消えているということもなさげでした。
つまりは、ないはずのものがあることになってた、かつ、/var/lib/dpkg/infoディレクトリに必要な(命名規則の拡張子を持つ)ファイル群がなかったから整合性がとれなかったということだったようで、対策が削除するだけって必要なものもなくなっちゃうんじゃ?という心配は要らないようです。
当然、この対策を行なっているPCは、任意のパッケージのインストール・アンインストール、依存関係の調整・構築などが行われているのでマシンスペックによっては他の作業が厳しくなる可能性はもとより、その時点で起動しないアプリなどもあり、作業内容によっては、別マシンを使うことになるでしょう。
これは、あくまで/var/lib/dpkg/infoを削除してしまった場合の対策の一例です。
大丈夫なはずですが、ことがことだけに実行にあたっては、置かれている状況をよく見回し、確かめた上、自己責任で。
任意のパッケージのインストールやアンインストールをしようにもできない、見た目なんともなさそうで起動もできるソフトウェアの動作も変な気がしなくもない。
/var/lib/dpkg/infoディレクトリを削除してしまった自覚はなかったが、端末の履歴を見て愕然、意に反し、見事なまでに削除してしまってる...。
このディレクトリは、一体何なのか調べてみると、Debian 管理者ハンドブック 5.2.2. 設定スクリプトによると「インストール済みパッケージの設定スクリプト」が全て含まれており、第2章 Debian パッケージ管理 2.5.9. dpkg コマンドによると「dpkgが作成するファイル」としてパッケージ名.conffiles/.list/.md5sums/.preinst/.postinst/.prerm等があるとのこと。
任意のパッケージをapt installやreinstallなどをしようとすると「dpkg: エラー: 新しいファイル '/var/lib/dpkg/info/format-new' を作成できません: そのようなファイルやディレクトリはありません」というエラーが出た。
そこで、とりあえず、冒頭の通り、infoディレクトリとそこにformat-newファイルを作成することでエラーを回避。
が、今度は、「dpkg: 警告: パッケージ 'xxx' のファイル一覧ファイルがありません。このパッケージには、現在インストールされているファイルがないものとします」という警告が多発。
この時、任意のパッケージのインストールはできたかに見え、起動もできるものの、メニューや起動後のアイコンなど不完全な状態で登録されているように見える状況に。
これってインストール済みパッケージを全部再インストールすれば、/var/lib/dpkg/infoも復活するだろうと、dpkg -lを元にしたとあるワンライナーを書いてやってみると、なんと5時間半程度もかかった...割りには解消せず。
dpkg --configure -aとしてもapt updateしても何も起こらない。
dpkg --auditしてみたら、検査にひっかかってるパッケージが結構ある。
サンプルとしてそこに載っている内、任意のpamanをdpkg -Pしてみたら、例の警告メッセージがズラーッと列挙され、最後に「...を削除しています」と出ているが、途中で終わっている感じ(、と思ったのは、勘違い、apt purgeと同じでこの時点で削除されていたっぽい)。
代わりに警告メッセージに出ているパッケージをapt reinstall(install --reinstall)すれば良いのかとやってみるが、今度は、「...はダウンロードできないため、再インストールは不可能です。」なんてエラーが表示されてダメ。
もちろん、回線はつながっているし、apt-cache searchすれば、存在するパッケージ。
ならばと、apt purge(remove --purge)してみたら、apt --audit結果から消えている!(dpkg -Pの時点で消えてたっぽいから、どっちでもよさ気。)
いくらでもあるので、その後、いくつか試してみると、やはり、apt --audit結果から消えている!
よっしゃ!ということで冒頭のワンライナーを実行してみるとapt --audit件数は0となり、その後、何事もなく、解決した次第。
(そう見えるだけじゃないよね?)
よって一通り、インストール済みパッケージをreinstallしてから、その上で検査にひっかかるパッケージをpurgeすればよいと...、というわけで冒頭の解決策にたどり着いた次第。
ここで、やめておけばよいものを、確認含め人柱的に/var/lib/dpkg/infoをmvしてdpkg -lリストからのreinstallをせずに、dpkg -auditからのpurgeをいきなりやってみました。
すると、どうやら、このpurge作業も、流れ行くログを見る限り、reinstallもやっているように見受けられました...が、勘違いだったようです。
なぜか、2時間半程度で終了...したものの、「これらを直すためには 'apt --fix-broken install' を実行する必要があるかもしれません。」「以下のパッケージには満たせない依存関係があります:」といったメッセージが多発...。
dpkg --auditしてみると実行前と同一か否かは不明も大量にヒット...。
というわけで、--fix-brokenつけて実行...と思いつつ、その前に何を血迷ったのか[Alt]+[F2]、[r]+[Enter]でメニューを更新したらPCがフリーズ...それもそのはず、この時点でdpkg --auditにはたくさんのパッケージがあったのだから...。
うーむ、Debianメニューからrecovery modeで入ってCLI起動、果たして再インストールを回避しつつ、復旧できるのか...。
確認作業で成功例を試さなかったばっかりに結局、インストーラ作ってインストールし直しました。