종속성을 제외하고 수동으로 설치된 최상위 패키지 나열

종속성을 제외하고 수동으로 설치된 최상위 패키지 나열

수동으로 설치된 패키지를 표시하는 방법에는 여러 가지가 있습니다 apt. 예를 들면 다음과 같습니다.

apt-mark showmanual

그러나 때로는 이 출력이 너무 많을 때도 있습니다. 예를 들어, 사용자가 패키지를 수동으로 설치하는 경우 foo:

apt-get install foo

...그리고 에 foo따라 다음이 출력됩니다.barbazapt-mark showmanual

bar
baz
foo

수동으로 설치된 상위 패키지만 나열하려면 어떻게 해야 합니까( foo)에는 종속성이 없습니다(아니 baz아니 bar)?


아래 코드는 작동하는 것 같지만암소 비슷한 일종의 영양 parallel수백 번 호출하는 것은 apt-rdepends너무 느립니다(4코어 CPU에서 3시간).

apt-mark showmanual | 
tee /tmp/foo | 
parallel "apt-rdepends -f Depends,PreDepends,Suggests,Recommends {} |
          tail +2" 2> /dev/null | 
tr -s ' ' '\n' | 
grep -v '[():]' | 
sort -Vu | 
grep -wv -f - /tmp/foo

답변1

이는 Python apt API를 사용하여 수행할 수 있습니다. 당신이 보는 패키지는 거기에 있는 실제 패키지이고 apt-mark showmanual,apt.cache.Cache()is_installedis_auto_installed가짜입니다. 그러나 종속성을 처리하는 것이 더 쉽습니다.

#! /usr/bin/env python3

from apt import cache

manual = set(pkg for pkg in cache.Cache() if pkg.is_installed and not pkg.is_auto_installed)
depends = set(dep_pkg.name for pkg in manual for dep in pkg.installed.get_dependencies('PreDepends', 'Depends', 'Recommends') for dep_pkg in dep)

print('\n'.join(pkg.name for pkg in manual if pkg.name not in depends))

심지어 여기에는 내가 볼 수 없을 것으로 예상되는 일부 패키지가 나열되어 있습니다( init, grep?!).

답변2

다음과 같이 첫 번째 수준 종속성 없이 수동으로 설치된 모든 패키지를 찾을 수 있습니다.

apt-mark showmanual | sort > manually-installed.txt

apt show $(apt-mark showmanual) 2>/dev/null | 
grep -e ^Depends -e ^Pre-Depends > deps1.txt

cat deps1.txt | 
sed 's/^Depends: //; s/^Pre-Depends: //; 
     s/(.*)//g; s/:any//g' > deps2.txt

cat deps2.txt | tr -d ',|' | tr ' ' '\n' | grep -v ^$ |
sort -u > all-dep-packages.txt

grep -v -F -f all-dep-packages.txt manually-installed.txt

다음과 같은 한 줄 매직을 사용할 수도 있습니다.

apt-mark showmanual | sort | grep -v -F -f <(apt show $(apt-mark showmanual) 2> /dev/null | grep -e ^Depends -e ^Pre-Depends | sed 's/^Depends: //; s/^Pre-Depends: //; s/(.*)//g; s/:any//g' | tr -d ',|' | tr ' ' '\n' | grep -v ^$ | sort -u)

답변3

다음 쉘 스크립트는 설치된 모든 종속성의 상위 항목을 검색합니다.

function get_installed_packages() {
    apt list --installed | sed 's#/.*##'
}

function get_installed_packages_with_deps() {
    dpkg-query --show --showformat '${Package} ${Depends} \
        ${Pre-Depends}\n' $(get_installed_packages) | 
    sed 's/ ([^(]*)//g; s/:any\|,//g'
}

function get_package_relations() {
    awk '{print $1 " " $1; for(i = 2; i <= NF; i++) print $1 " " $i;}'
}

function add_marker() {
    echo "~ ~"
}

function resolve_parents() {
    tsort | sed -n '1,/~/ p' | head -n -1
}

(get_installed_packages_with_deps | get_package_relations; add_marker) | 
resolve_parents

tsort이 스크립트에서는 이를 사용하고 있습니다 . 종속성 없이 끝에 태그를 추가하면 해당 태그도 종속성 없는 결과의 마지막 항목이 될 것이라고 가정합니다. 따라서 종속성이 없는 마지막 패키지와 종속성이 있는 첫 번째 패키지를 구분할 수 있습니다.

이 솔루션에서 문제를 발견했습니다.
종속성 그래프에 주기가 있습니다. 이러한 항목은 무시됩니다 tsort.

답변4

바라보다이 답변은 Askubuntu에 있습니다.apt-mark showmanual, 이는 다음 내용을 사용하여 비교됩니다 /var/log/installer/initial-status.gz.

comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u)

그러면 Ubuntu를 새로 설치한 이후 수동으로 추가한 패키지가 제공됩니다.

관련 정보