誤ってインストールされたパッケージを削除する

誤ってインストールされたパッケージを削除する

Pop!_OS 用の system76 ppa を誤って Ubuntu 20.04 インストールに追加してしまったようです。(本当に不思議なのは、これに気付いていなかったことです...)

その間、私は見つけたリポジトリのリストにある PPA とエントリを削除しました。システムはほぼ正常に戻りました。それでも、少なくとも次の出力から私が解釈しているように、まだ残っているものがあると思います。

$ apt list --installed  | grep pop[0-9]

accountsservice/now 0.6.55-0ubuntu13.2pop0~1605745773~20.04~d9482b1 amd64 [installed,local]
gnome-settings-daemon-common/now 3.36.1-0ubuntu1pop0~1596026424~20.04~8296153 all [installed,local]
gnome-terminal-data/now 3.36.2-1ubuntu1~20.04pop0~1594780610~20.04~8048ed7 all [installed,local]
gnome-terminal/now 3.36.2-1ubuntu1~20.04pop0~1594780610~20.04~8048ed7 amd64 [installed,local]
...

これらがどのリポジトリに属しているかをどうやって確認すればいいのでしょうか。また、これらのパッケージを現在アクティブなリポジトリに含まれているバージョンにダウングレードするにはどうすればいいのでしょうか。

たとえば、次のようになります。

$ apt policy gnome-settings-daemon-common
gnome-settings-daemon-common:
  Installed: 3.36.1-0ubuntu1pop0~1596026424~20.04~8296153
  Candidate: 3.36.1-0ubuntu1pop0~1596026424~20.04~8296153
  Version table:
 *** 3.36.1-0ubuntu1pop0~1596026424~20.04~8296153 100
        100 /var/lib/dpkg/status
     3.36.1-0ubuntu1 500
        500 http://xx.archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages
        500 http://xx.archive.ubuntu.com/ubuntu focal-updates/main i386 Packages
     3.36.0-1ubuntu2 500
        500 http://xx.archive.ubuntu.com/ubuntu focal/main amd64 Packages
        500 http://xx.archive.ubuntu.com/ubuntu focal/main i386 Packages

そして:

$ apt-cache madison  gnome-settings-daemon-common
gnome-settings-daemon-common | 3.36.1-0ubuntu1 | http://xx.archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages
gnome-settings-daemon-common | 3.36.1-0ubuntu1 | http://xx.archive.ubuntu.com/ubuntu focal-updates/main i386 Packages
gnome-settings-daemon-common | 3.36.0-1ubuntu2 | http://xx.archive.ubuntu.com/ubuntu focal/main amd64 Packages
gnome-settings-daemon-common | 3.36.0-1ubuntu2 | http://xx.archive.ubuntu.com/ubuntu focal/main i386 Packages
gnome-settings-daemon | 3.36.0-1ubuntu2 | http://xx.archive.ubuntu.com/ubuntu focal/main Sources
gnome-settings-daemon | 3.36.1-0ubuntu1 | http://xx.archive.ubuntu.com/ubuntu focal-updates/main Sources

これは、現在インストールされているバージョンがリポジトリに含まれていないことを示していると解釈します。

しかし、リポジトリのバージョンを元に戻すにはどうしたらいいのでしょうか?理想的には、全てパッケージ...

アップデート私は現在、 を使用して、すべてのパッケージを手動で必要なパッケージに置き換えていますapt-get install package=version。 それぞれについて必要なバージョンを調べる必要がありapt policy、依存関係を満たすために一度に多数のパッケージを置き換えることもあったため、これは非常に面倒でした。 私の問題は解決しましたが、このようなクリーンアップをより効率的に行う方法にはまだ非常に興味があります。

答え1

こうした面倒な手作業によるクリーンアップ作業をすべて終えた後、最終的には、アクティブなリポジトリに存在しないパッケージ、またはリポジトリにあるバージョンよりも新しいバージョンがインストールされているパッケージをすべて識別する Python スクリプトも作成しました。

以下のコードは簡単な修正であり、美しさのコンテストで優勝できるほどではありませんが、私にとっては十分機能しました。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Identify all packages that are not in active repositories or for
which newer versions are installed.
"""

import re
import subprocess
from pprint import pprint


def get_packages():
    vers = subprocess.run("apt-show-versions", shell=True, capture_output=True)
    vers = vers.stdout.decode("utf-8").splitlines()
    vers = [y for y in (x.strip() for x in vers) if y]
    not_in_archive = {}
    newer_than_archive = {}
    others = {}
    for pkg in vers:
        p = [x.strip() for x in pkg.split(' ', 2)]
        name = p[0]
        vers = p[1]
        status = p[2] if len(p) == 3 else ''
        if vers == 'not' and status == 'installed':
            continue
        if status == 'uptodate':
            continue

        tmp = {name: {'vers': vers}}
        if status == 'installed: No available version in archive':
            not_in_archive.update(tmp)
        elif status == 'newer than version in archive':
            newer_than_archive.update(tmp)
        else:
            others.update(tmp)
            others[name][status] = status

    return not_in_archive, newer_than_archive, others


def get_version(pkg):
    vers = subprocess.run("apt policy {}".format(pkg),
                          shell=True, capture_output=True)
    vers = vers.stdout.decode("utf-8").splitlines()

    vt = re.compile(r'^ +version table:', re.IGNORECASE)
    stars = re.compile(r'^ \*\*\* *')

    res = []

    while True:
        line = vers.pop(0)
        if vt.match(line):
            break

    for i, line in enumerate(vers):
        if line[:8].strip():
            s = line[:5]
            v = line[5:].split(' ', 1)[0]
            installed = bool(stars.match(s))
        else:
            p, a = line[8:].split(' ', 1)
            res.append({'installed': installed,
                        'version': v,
                        'prio': p,
                        'archive': a})
    return res


if __name__ == '__main__':

    missing, newer, rest = get_packages()

    url = re.compile(r'^https?://', re.IGNORECASE)

    res = {}

    for p in newer:
        v = get_version(p)
        for x in v:
            if url.match(x['archive']):
                res[p] = x['version']
                break

    if missing:
        print("===== packages not in repositories =====")
        print(' '.join(p for p in missing))
        print()

    if rest:
        print("===== packages with other status =====")
        pprint(rest)
        print()

    if res:
        print("===== command to downgrade =====")
        print('sudo apt-get install {}'.format(
            ' '.join('{}={}'.format(p, v) for p, v in res.items())))

例えば、darktableとkicadのPPAを無効にすると、

===== packages not in repositories =====
darktable-dbg:amd64 libpng12-0:amd64 zoom:amd64

===== command to downgrade =====
sudo apt-get install darktable:amd64=3.0.1-0ubuntu1 kicad:amd64=5.1.5+dfsg1-2build2 kicad-demos:all=5.1.5+dfsg1-2build2 kicad-doc-en:all=5.1.5+dfsg1-2build2 kicad-footprints:all=5.1.5-1 kicad-libraries:all=5.1.5+dfsg1-2build2 kicad-packages3d:all=5.1.5-1 kicad-symbols:all=5.1.5-1 kicad-templates:all=5.1.5-1

最後のコマンドはインストールされたパッケージをダウングレードするため、上記のパッケージは で削除する必要がありますapt-get remove ...

(PPA を削除するだけで、システム内の他のすべてが「クリーン」である場合は、PPA パージが最適な方法であることは理解していますが、常にそうであるとは限りません)

関連情報