注意: 本記事に書いてあることを実際に試して環境がぶっ壊れてもなんの責任も負いませんし、サンダルで散歩した時に親指を怪我したとしてもなんの責任も取りません。


導入 Link to this heading

大学院の募集が始まり研究計画書が書けないということでイライラすることはよくあると思います。

イライラしたときに、aptのデバッグをするためにソースからビルドして、それを間違えて環境にインストールしてしまうこともよくあると思います。 そうすると、おそらく以下のように/etc/aptではなく/usr/local/etc/aptを見に行くようになってしまい、余計イライラが蓄積していきます:

.bash
1W: Unable to read /usr/local/etc/apt/apt.conf.d/ - DirectoryExists (2: No such file or directory)
2W: Unable to read /usr/local/etc/apt/sources.list.d/ - DirectoryExists (2: No such file or directory)
3W: Unable to read /usr/local/etc/apt/sources.list - RealFileExists (2: No such file or directory)
4W: Unable to read /usr/local/etc/apt/preferences.d/ - DirectoryExists (2: No such file or directory)

apt自体は異常な量のconfig名前空間を持っており、それを指定することで一時的にetcディレクトリを指定することはできます。 例えばsudo apt -oDir::Etc=/etc/apt install hogeとすることでetcを指定することができます。 それにしたってinstall時に以下のようなエラーが出ます:

.bash
 1After this operation, 120 MB of additional disk space will be used.
 2Do you want to continue? [Y/n] Y
 3E: Cannot get debconf version. Is debconf installed?
 4debconf: apt-extracttemplates failed: No such file or directory
 5Extracting templates from packages: 30%E: Cannot get debconf version. Is debconf installed?
 6debconf: apt-extracttemplates failed: No such file or directory
 7Extracting templates from packages: 61%E: Cannot get debconf version. Is debconf installed?
 8debconf: apt-extracttemplates failed: No such file or directory
 9Extracting templates from packages: 91%E: Cannot get debconf version. Is debconf installed?
10debconf: apt-extracttemplates failed: No such file or directory
11Extracting templates from packages: 100%
12Could not exec dpkg!
13E: Sub-process /usr/local/bin/dpkg returned an error code (100)

ここまで来ると、およそ大抵の人はイライラが蓄積し、aptをリインストールすることになると思います。 しかし、aptだけリインストールしても上の症状は全く変わりません。

そうするとほとんどの人はそのイライラから以下のようなコマンドを打つことになると思います。

.bash
1wataru@skbpc:~: 20:43:34 Thu Jun 03
2$ sudo rm /usr/bin/dpkg
3wataru@skbpc:~: 20:43:50 Thu Jun 03
4$ sudo rm /usr/bin/apt

ここで、1分くらい絶望に暮れましょう。

dpkgのリインストール Link to this heading

多分、UbuntuのISOイメージに入ってるaptとdpkgを使ってやるのが最もクリーンだと思いますが、以下ではちょっとdirtyかもしれない方法を使います。 ISO入ったCD-ROMって、なくしがちだもんね。

やることは、aptがやってくれることを手動でやるだけです。

まずはIndexファイルを取ってきます:

.bash
 1$ wget http://security.ubuntu.com/ubuntu/dists/focal/main/binary-adm64/Packages.gz
 2--2021-06-03 21:39:20--  http://security.ubuntu.com/ubuntu/dists/focal/main/binary-adm64/Packages.gz
 3Resolving security.ubuntu.com (security.ubuntu.com)... 2001:67c:1562::15, 2001:67c:1562::18, 91.189.91.39, ...
 4Connecting to security.ubuntu.com (security.ubuntu.com)|2001:67c:1562::15|:80... connected.
 5HTTP request sent, awaiting response... 404 Not Found
 62021-06-03 21:39:21 ERROR 404: Not Found.
 7 
 8$ wget http://security.ubuntu.com/ubuntu/dists/focal/main/binary-amd64/Packages.gz
 9--2021-06-03 21:39:34--  http://security.ubuntu.com/ubuntu/dists/focal/main/binary-amd64/Packages.gz
10Resolving security.ubuntu.com (security.ubuntu.com)... 2001:67c:1562::15, 2001:67c:1562::18, 91.189.91.39, ...
11Connecting to security.ubuntu.com (security.ubuntu.com)|2001:67c:1562::15|:80... connected.
12HTTP request sent, awaiting response... 200 OK
13Length: 1274738 (1.2M) [application/x-gzip]
14Saving to: ‘Packages.gz’
15 
16Packages.gz            100%[==========================>]   1.21M   916KB/s    in 1.4s
17 
182021-06-03 21:39:36 (916 KB/s) - ‘Packages.gz’ saved [1274738/1274738]
19 
20$ gunzip ./Packages.gz

ここで一回binary-amd64binary-adm64とtypoすることが重要です。 distroとarchとcomponentは自分が使っているものに合わせてください。そしたら、そのIndexファイルを見てdpkgを探します。

.bash
 1Package: dpkg
 2Architecture: amd64
 3Version: 1.19.7ubuntu3
 4Multi-Arch: foreign
 5Priority: required
 6Essential: yes
 7Section: admin
 8Origin: Ubuntu
 9Maintainer: Ubuntu Developers <[email protected]>
10Original-Maintainer: Dpkg Developers <[email protected]>
11Bugs: https://bugs.launchpad.net/ubuntu/+filebug
12Installed-Size: 6740
13Pre-Depends: libbz2-1.0, libc6 (>= 2.15), liblzma5 (>= 5.2.2), libselinux1 (>= 2.3), libzstd1 (>= 1.3.2), zlib1g (>= 1:1.1.4)
14Depends: tar (>= 1.28-1)
15Suggests: apt, debsig-verify
16Breaks: acidbase (<= 1.4.5-4), amule (<< 2.3.1+git1a369e47-3), beep (<< 1.3-4), im (<< 1:151-4), libapt-pkg5.0 (<< 1.7~b), libdpkg-perl (<< 1.18.11), lsb-base (<< 10.2019031300), netselect (<< 0.3.ds1-27), pconsole (<< 1.0-12), phpgacl (<< 3.3.7-7.3), pure-ftpd (<< 1.0.43-1), systemtap (<< 2.8-1), terminatorx (<< 4.0.1-1), xvt (<= 2.1-20.1)
17Filename: pool/main/d/dpkg/dpkg_1.19.7ubuntu3_amd64.deb
18Size: 1127856
19MD5sum: f595c79475d3c2ac808eaac389071c35
20SHA1: b9cb6b292865ec85bca1021085bc0e81e160e676
21SHA256: 76132be95c7199f902767fb329e0f33210ac5b5b1816746543bc75f795d9a37c
22Homepage: https://wiki.debian.org/Teams/Dpkg
23Description: Debian package management system
24Task: minimal
25Description-md5: 2f156c6a30cc39895ad3487111e8c190

Filenameを見ると、バイナリの場所が書いてあるのでそれを取ってきます。

.bash
1$ wget http://security.ubuntu.com/ubuntu/pool/main/d/dpkg/dpkg_1.19.7ubuntu3_amd64.deb

dpkgがないため、バイナリなくてやばいなり、という渾身のギャグを一発かました後、直接extractしてバイナリを取り出します。

.bash
1mkdir nirugiri && cd nirugiri
2ar x ../dpkg_1.19.7ubuntu3_amd64.deb
3unxz ./data.tar.xz && tar xvf ./data.tar
4sudo cp ./usr/bin/dpkg /usr/bin/

これでdpkgのリインストールは終わり。

aptのリインストール Link to this heading

apt自体は、上の方法で同様にやればOK。しかも今回はdpkgを使えます。ありがて〜〜〜。

aptのインストールが終わったら念の為dpkgをaptからリインストールするといいって実家を出る時にばあちゃんが言ってました。

古いaptを消す Link to this heading

これでやっと振り出しに戻りますが、依然aptは/usr/local/etc/aptを見続けます。 ストーカー並みに見続けます。

なので、straceして何が悪さをしているかを見ます。

.bash
1openat(AT_FDCWD, "/usr/local/lib/libapt-private.so.0.0", O_RDONLY|O_CLOEXEC) = 3

この辺ですね。抹殺します。

.bash
1sudo mv /usr/local/lib/libapt-private.so.0.0 /usr/local/lib/libapt-private.so.0.0.kasu
2sudo mv /usr/local/lib/libapt-pkg.so /usr/local/lib/libapt-pkg.so.kasu

恨みを込めて、拡張子はkasuにしておくのがおすすめです。

アウトロ Link to this heading

いかがだったでしょうか?

カス記事を書くのはいつだって楽しいし、晩御飯はいつ食べても美味しいことが知られています。

参考 Link to this heading