依存関係を除く手動でインストールされた最上位パッケージのリスト

依存関係を除く手動でインストールされた最上位パッケージのリスト

手動でインストールされたパッケージを表示する方法はいくつかあります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 showmanualapt.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))

ここには、私が見ることができないと予想されるいくつかのパッケージがリストされています(initgrep?!)。

答え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

次の1行マジックを使用することもできます。

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の新規インストール後に手動で追加したパッケージが提供されます。

関連情報