종속성없이 수동으로 설치된 최상위 패키지 목록 showmanual출력됩니다. bar baz foo 어떻게 우리는 최상위 레벨 수동으로 설치

를 사용하여 수동으로 설치된 패키지를 표시하는 방법에는 여러 가지가 있습니다 apt.

apt-mark showmanual

그러나 때로는 그 결과가 너무 많습니다. 예를 들어 사용자가 수동으로 패키지를 설치 한 경우 foo:

apt-get install foo

…에 foo의존 하면 다음 barbaz같이 apt-mark showmanual출력됩니다.

bar
baz
foo

어떻게 우리는 최상위 레벨 수동으로 설치 패키지를 (나열 할 수 있습니다 즉, foo (의존성없이) 하지 baz않으며, bar)?


다음 코드는 작동하는 것으로 보이지만 GNU 가 수백 번 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



답변

이것은 Python apt API를 사용하여 수행 할 수 있습니다. 당신이 볼 수있는 패키지는 apt-mark showmanual정확히 것들입니다 apt.cache.Cache()있는 is_installed사실이고 is_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?!) 가 나열되어 있습니다 .


답변

다음 쉘 스크립트는 설치된 모든 종속성의 부모를 검색합니다.

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이 스크립트에서 사용 했습니다. 종속성없이 끝에 마커를 추가하면 마커가 결과에 종속성이없는 마지막 항목이 될 것이라고 가정합니다. 따라서 종속성이없는 마지막 패키지와 depenencies가있는 첫 번째 패키지를 구별 할 수 있습니다.

이 솔루션의 한 가지 문제점을 발견
했습니다. 종속성 그래프에주기가 있습니다. 해당 항목은로 무시됩니다 tsort.


답변

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

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)


답변