실수로 설치된 패키지 제거

실수로 설치된 패키지 제거

실수로 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-purge가 갈 길이라는 것을 이해하지만 항상 그런 것은 아닐 수도 있습니다)

관련 정보